Revert previous change that allowed some operations to be performed without holding the lock, as it introduced a race condition in certain multithreaded scenarios.
diff --git a/asio/include/asio/detail/epoll_reactor.hpp b/asio/include/asio/detail/epoll_reactor.hpp index 6d685f8..b30f191 100644 --- a/asio/include/asio/detail/epoll_reactor.hpp +++ b/asio/include/asio/detail/epoll_reactor.hpp
@@ -55,8 +55,6 @@ descriptor_state* next_; descriptor_state* prev_; - bool op_queue_is_empty_[max_ops]; - mutex mutex_; epoll_reactor* reactor_; int descriptor_;
diff --git a/asio/include/asio/detail/impl/epoll_reactor.ipp b/asio/include/asio/detail/impl/epoll_reactor.ipp index 859e284..bd60515 100644 --- a/asio/include/asio/detail/impl/epoll_reactor.ipp +++ b/asio/include/asio/detail/impl/epoll_reactor.ipp
@@ -155,10 +155,6 @@ descriptor_data->reactor_ = this; descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; - - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); } epoll_event ev = { 0, { 0 } }; @@ -184,10 +180,6 @@ descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; descriptor_data->op_queue_[op_type].push(op); - - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); } epoll_event ev = { 0, { 0 } }; @@ -219,22 +211,6 @@ return; } - bool perform_speculative = allow_speculative; - if (perform_speculative) - { - if (descriptor_data->op_queue_is_empty_[op_type] - && (op_type != read_op - || descriptor_data->op_queue_is_empty_[except_op])) - { - if (op->perform()) - { - io_service_.post_immediate_completion(op); - return; - } - perform_speculative = false; - } - } - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (descriptor_data->shutdown_) @@ -243,17 +219,11 @@ return; } - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); - - if (descriptor_data->op_queue_is_empty_[op_type]) + if (descriptor_data->op_queue_[op_type].empty()) { if (allow_speculative) { - if (perform_speculative - && (op_type != read_op - || descriptor_data->op_queue_is_empty_[except_op])) + if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) { if (op->perform()) { @@ -274,7 +244,6 @@ } descriptor_data->op_queue_[op_type].push(op); - descriptor_data->op_queue_is_empty_[op_type] = false; io_service_.work_started(); }
diff --git a/asio/include/asio/detail/impl/kqueue_reactor.ipp b/asio/include/asio/detail/impl/kqueue_reactor.ipp index 3a9cf01..209f367 100644 --- a/asio/include/asio/detail/impl/kqueue_reactor.ipp +++ b/asio/include/asio/detail/impl/kqueue_reactor.ipp
@@ -132,10 +132,6 @@ descriptor_data->descriptor_ = descriptor; descriptor_data->shutdown_ = false; - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); - return 0; } @@ -151,10 +147,6 @@ descriptor_data->shutdown_ = false; descriptor_data->op_queue_[op_type].push(op); - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); - struct kevent event; switch (op_type) { @@ -195,21 +187,6 @@ return; } - if (allow_speculative) - { - if (descriptor_data->op_queue_is_empty_[op_type] - && (op_type != read_op - || descriptor_data->op_queue_is_empty_[except_op])) - { - if (op->perform()) - { - io_service_.post_immediate_completion(op); - return; - } - allow_speculative = false; - } - } - mutex::scoped_lock descriptor_lock(descriptor_data->mutex_); if (descriptor_data->shutdown_) @@ -218,16 +195,12 @@ return; } - for (int i = 0; i < max_ops; ++i) - descriptor_data->op_queue_is_empty_[i] = - descriptor_data->op_queue_[i].empty(); - - bool first = descriptor_data->op_queue_is_empty_[op_type]; + bool first = descriptor_data->op_queue_[op_type].empty(); if (first) { if (allow_speculative) { - if (op_type != read_op || descriptor_data->op_queue_is_empty_[except_op]) + if (op_type != read_op || descriptor_data->op_queue_[except_op].empty()) { if (op->perform()) { @@ -240,7 +213,6 @@ } descriptor_data->op_queue_[op_type].push(op); - descriptor_data->op_queue_is_empty_[op_type] = false; io_service_.work_started(); if (first)
diff --git a/asio/include/asio/detail/kqueue_reactor.hpp b/asio/include/asio/detail/kqueue_reactor.hpp index e420f63..533868c 100644 --- a/asio/include/asio/detail/kqueue_reactor.hpp +++ b/asio/include/asio/detail/kqueue_reactor.hpp
@@ -65,8 +65,6 @@ descriptor_state* next_; descriptor_state* prev_; - bool op_queue_is_empty_[max_ops]; - mutex mutex_; int descriptor_; op_queue<reactor_op> op_queue_[max_ops];