From d02ff9fd317abc2ca4e8f2d45c3b37b47c4ce0ff Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Mon, 14 Jan 2008 13:24:28 +0000 Subject: [PATCH] Don't call epoll_wait/kevent if there are no old operations (where old means added prior to the last epoll_wait/kevent call) needing to be demultiplexed. [SVN r42755] --- include/boost/asio/detail/epoll_reactor.hpp | 14 ++++++++++++-- include/boost/asio/detail/kqueue_reactor.hpp | 14 ++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/include/boost/asio/detail/epoll_reactor.hpp b/include/boost/asio/detail/epoll_reactor.hpp index 6cd72523..3fa36efa 100644 --- a/include/boost/asio/detail/epoll_reactor.hpp +++ b/include/boost/asio/detail/epoll_reactor.hpp @@ -67,7 +67,8 @@ public: pending_cancellations_(), stop_thread_(false), thread_(0), - shutdown_(false) + shutdown_(false), + need_epoll_wait_(true) { // Start the reactor's internal thread only if needed. if (Own_Thread) @@ -388,7 +389,9 @@ private: // Block on the epoll descriptor. epoll_event events[128]; - int num_events = epoll_wait(epoll_fd_, events, 128, timeout); + int num_events = (block || need_epoll_wait_) + ? epoll_wait(epoll_fd_, events, 128, timeout) + : 0; lock.lock(); wait_in_progress_ = false; @@ -479,6 +482,10 @@ private: cancel_ops_unlocked(pending_cancellations_[i]); pending_cancellations_.clear(); + // Determine whether epoll_wait should be called when the reactor next runs. + need_epoll_wait_ = !read_op_queue_.empty() + || !write_op_queue_.empty() || !except_op_queue_.empty(); + cleanup_operations_and_timers(lock); } @@ -633,6 +640,9 @@ private: // Whether the service has been shut down. bool shutdown_; + + // Whether we need to call epoll_wait the next time the reactor is run. + bool need_epoll_wait_; }; } // namespace detail diff --git a/include/boost/asio/detail/kqueue_reactor.hpp b/include/boost/asio/detail/kqueue_reactor.hpp index c4668e7a..04261e83 100644 --- a/include/boost/asio/detail/kqueue_reactor.hpp +++ b/include/boost/asio/detail/kqueue_reactor.hpp @@ -75,7 +75,8 @@ public: pending_cancellations_(), stop_thread_(false), thread_(0), - shutdown_(false) + shutdown_(false), + need_kqueue_wait_(true) { // Start the reactor's internal thread only if needed. if (Own_Thread) @@ -374,7 +375,9 @@ private: // Block on the kqueue descriptor. struct kevent events[128]; - int num_events = kevent(kqueue_fd_, 0, 0, events, 128, timeout); + int num_events = (block || need_kqueue_wait_) + ? kevent(kqueue_fd_, 0, 0, events, 128, timeout) + : 0; lock.lock(); wait_in_progress_ = false; @@ -479,6 +482,10 @@ private: cancel_ops_unlocked(pending_cancellations_[i]); pending_cancellations_.clear(); + // Determine whether kqueue needs to be called next time the reactor is run. + need_kqueue_wait_ = !read_op_queue_.empty() + || !write_op_queue_.empty() || !except_op_queue_.empty(); + cleanup_operations_and_timers(lock); } @@ -631,6 +638,9 @@ private: // Whether the service has been shut down. bool shutdown_; + + // Whether we need to call kqueue the next time the reactor is run. + bool need_kqueue_wait_; }; } // namespace detail