summaryrefslogtreecommitdiff
path: root/boost/asio/detail/impl/epoll_reactor.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/asio/detail/impl/epoll_reactor.ipp')
-rw-r--r--boost/asio/detail/impl/epoll_reactor.ipp50
1 files changed, 38 insertions, 12 deletions
diff --git a/boost/asio/detail/impl/epoll_reactor.ipp b/boost/asio/detail/impl/epoll_reactor.ipp
index 771edea67c..073bd08825 100644
--- a/boost/asio/detail/impl/epoll_reactor.ipp
+++ b/boost/asio/detail/impl/epoll_reactor.ipp
@@ -127,7 +127,7 @@ void epoll_reactor::fork_service(boost::asio::io_service::fork_event fork_ev)
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)
@@ -159,7 +159,8 @@ int epoll_reactor::register_descriptor(socket_type descriptor,
}
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)
@@ -184,7 +185,8 @@ int epoll_reactor::register_internal_descriptor(
}
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)
@@ -222,23 +224,47 @@ void epoll_reactor::start_op(int op_type, socket_type descriptor,
if (descriptor_data->op_queue_[op_type].empty())
{
- if (allow_speculative)
+ if (allow_speculative
+ && (op_type != read_op
+ || descriptor_data->op_queue_[except_op].empty()))
{
- if (op_type != read_op || descriptor_data->op_queue_[except_op].empty())
+ if (op->perform())
{
- if (op->perform())
+ descriptor_lock.unlock();
+ io_service_.post_immediate_completion(op);
+ return;
+ }
+
+ if (op_type == write_op)
+ {
+ if ((descriptor_data->registered_events_ & EPOLLOUT) == 0)
{
- descriptor_lock.unlock();
- io_service_.post_immediate_completion(op);
- return;
+ 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_ = boost::system::error_code(errno,
+ boost::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);
}
@@ -440,7 +466,7 @@ int epoll_reactor::do_epoll_create()
errno = EINVAL;
#endif // defined(EPOLL_CLOEXEC)
- if (fd == -1 && errno == EINVAL)
+ if (fd == -1 && (errno == EINVAL || errno == ENOSYS))
{
fd = epoll_create(epoll_size);
if (fd != -1)