Eliminate a lock/unlock pair when rescheduling a strand.
diff --git a/asio/include/asio/detail/impl/strand_service.ipp b/asio/include/asio/detail/impl/strand_service.ipp index f4290cd..e264fb8 100644 --- a/asio/include/asio/detail/impl/strand_service.ipp +++ b/asio/include/asio/detail/impl/strand_service.ipp
@@ -37,7 +37,7 @@ impl_->mutex_.unlock(); if (more_handlers) - owner_->post_immediate_completion(impl_); + owner_->post_private_immediate_completion(impl_); } };
diff --git a/asio/include/asio/detail/impl/task_io_service.ipp b/asio/include/asio/detail/impl/task_io_service.ipp index 49f6265..6b3b247 100755 --- a/asio/include/asio/detail/impl/task_io_service.ipp +++ b/asio/include/asio/detail/impl/task_io_service.ipp
@@ -132,7 +132,7 @@ this_thread.wakeup_event = &wakeup_event; op_queue<operation> private_op_queue; #if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) - this_thread.private_op_queue = one_thread_ == 1 ? &private_op_queue : 0; + this_thread.private_op_queue = &private_op_queue; #else // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) this_thread.private_op_queue = 0; #endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) @@ -183,7 +183,7 @@ this_thread.wakeup_event = 0; op_queue<operation> private_op_queue; #if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) - this_thread.private_op_queue = one_thread_ == 1 ? &private_op_queue : 0; + this_thread.private_op_queue = &private_op_queue; #else // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) this_thread.private_op_queue = 0; #endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) @@ -310,6 +310,32 @@ } } +void task_io_service::post_private_immediate_completion( + task_io_service::operation* op) +{ + work_started(); + post_private_deferred_completion(op); +} + +void task_io_service::post_private_deferred_completion( + task_io_service::operation* op) +{ +#if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + if (thread_info* this_thread = thread_call_stack::contains(this)) + { + if (this_thread->private_op_queue) + { + this_thread->private_op_queue->push(op); + return; + } + } +#endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + + mutex::scoped_lock lock(mutex_); + op_queue_.push(op); + wake_one_thread_and_unlock(lock); +} + void task_io_service::abandon_operations( op_queue<task_io_service::operation>& ops) {
diff --git a/asio/include/asio/detail/task_io_service.hpp b/asio/include/asio/detail/task_io_service.hpp index f7b4870..517cd4d 100644 --- a/asio/include/asio/detail/task_io_service.hpp +++ b/asio/include/asio/detail/task_io_service.hpp
@@ -111,6 +111,16 @@ // that work_started() was previously called for each operation. ASIO_DECL void post_deferred_completions(op_queue<operation>& ops); + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() has not yet been + // called for the operation. + ASIO_DECL void post_private_immediate_completion(operation* op); + + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() was previously called + // for the operation. + ASIO_DECL void post_private_deferred_completion(operation* op); + // Process unfinished operations as part of a shutdown_service operation. // Assumes that work_started() was previously called for the operations. ASIO_DECL void abandon_operations(op_queue<operation>& ops);
diff --git a/asio/include/asio/detail/win_iocp_io_service.hpp b/asio/include/asio/detail/win_iocp_io_service.hpp index 68f209e..20bf28f 100644 --- a/asio/include/asio/detail/win_iocp_io_service.hpp +++ b/asio/include/asio/detail/win_iocp_io_service.hpp
@@ -134,6 +134,22 @@ ASIO_DECL void post_deferred_completions( op_queue<win_iocp_operation>& ops); + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() has not yet been + // called for the operation. + void post_private_immediate_completion(win_iocp_operation* op) + { + post_immediate_completion(op); + } + + // Request invocation of the given operation using the thread-private queue + // and return immediately. Assumes that work_started() was previously called + // for the operation. + void post_private_deferred_completion(win_iocp_operation* op) + { + post_deferred_completion(op); + } + // Process unfinished operations as part of a shutdown_service operation. // Assumes that work_started() was previously called for the operations. ASIO_DECL void abandon_operations(op_queue<operation>& ops);