Added lazy registration for EPOLLOUT.
diff --git a/asio/include/asio/detail/epoll_reactor.hpp b/asio/include/asio/detail/epoll_reactor.hpp index b30f191..7a51d23 100644 --- a/asio/include/asio/detail/epoll_reactor.hpp +++ b/asio/include/asio/detail/epoll_reactor.hpp
@@ -19,6 +19,7 @@ #if defined(ASIO_HAS_EPOLL) +#include <boost/cstdint.hpp> #include <boost/limits.hpp> #include "asio/io_service.hpp" #include "asio/detail/atomic_count.hpp" @@ -58,6 +59,7 @@ mutex mutex_; epoll_reactor* reactor_; int descriptor_; + boost::uint32_t registered_events_; op_queue<reactor_op> op_queue_[max_ops]; bool shutdown_;
diff --git a/asio/include/asio/detail/impl/epoll_reactor.ipp b/asio/include/asio/detail/impl/epoll_reactor.ipp index 6ca5bdc..1a58b72 100644 --- a/asio/include/asio/detail/impl/epoll_reactor.ipp +++ b/asio/include/asio/detail/impl/epoll_reactor.ipp
@@ -126,7 +126,7 @@ for (descriptor_state* state = registered_descriptors_.first(); state != 0; state = state->next_) { - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.events = state->registered_events_; ev.data.ptr = state; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, state->descriptor_, &ev); if (result != 0) @@ -158,7 +158,8 @@ } epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET; + descriptor_data->registered_events_ = ev.events; ev.data.ptr = descriptor_data; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); if (result != 0) @@ -183,7 +184,8 @@ } epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.events = EPOLLIN | EPOLLERR | EPOLLHUP | EPOLLPRI | EPOLLET; + descriptor_data->registered_events_ = ev.events; ev.data.ptr = descriptor_data; int result = epoll_ctl(epoll_fd_, EPOLL_CTL_ADD, descriptor, &ev); if (result != 0) @@ -231,12 +233,37 @@ io_service_.post_immediate_completion(op); return; } + + if (op_type == write_op) + { + if ((descriptor_data->registered_events_ & EPOLLOUT) == 0) + { + epoll_event ev = { 0, { 0 } }; + ev.events = descriptor_data->registered_events_ | EPOLLOUT; + ev.data.ptr = descriptor_data; + if (epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev) == 0) + { + descriptor_data->registered_events_ |= ev.events; + } + else + { + op->ec_ = asio::error_code(errno, + asio::error::get_system_category()); + io_service_.post_immediate_completion(op); + return; + } + } + } } else { + if (op_type == write_op) + { + descriptor_data->registered_events_ |= EPOLLOUT; + } + epoll_event ev = { 0, { 0 } }; - ev.events = EPOLLIN | EPOLLERR | EPOLLHUP - | EPOLLOUT | EPOLLPRI | EPOLLET; + ev.events = descriptor_data->registered_events_; ev.data.ptr = descriptor_data; epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev); }