summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/detail/impl/strand_service.ipp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/detail/impl/strand_service.ipp')
-rw-r--r--3rdparty/asio/include/asio/detail/impl/strand_service.ipp43
1 files changed, 34 insertions, 9 deletions
diff --git a/3rdparty/asio/include/asio/detail/impl/strand_service.ipp b/3rdparty/asio/include/asio/detail/impl/strand_service.ipp
index 16946dcab67..58d657c9853 100644
--- a/3rdparty/asio/include/asio/detail/impl/strand_service.ipp
+++ b/3rdparty/asio/include/asio/detail/impl/strand_service.ipp
@@ -2,7 +2,7 @@
// detail/impl/strand_service.ipp
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -43,7 +43,8 @@ struct strand_service::on_do_complete_exit
strand_service::strand_service(asio::io_context& io_context)
: asio::detail::service_base<strand_service>(io_context),
- io_context_(asio::use_service<io_context_impl>(io_context)),
+ io_context_(io_context),
+ io_context_impl_(asio::use_service<io_context_impl>(io_context)),
mutex_(),
salt_(0)
{
@@ -90,18 +91,44 @@ bool strand_service::running_in_this_thread(
return call_stack<strand_impl>::contains(impl) != 0;
}
-bool strand_service::do_dispatch(implementation_type& impl, operation* op)
+struct strand_service::on_dispatch_exit
+{
+ io_context_impl* io_context_impl_;
+ strand_impl* impl_;
+
+ ~on_dispatch_exit()
+ {
+ impl_->mutex_.lock();
+ impl_->ready_queue_.push(impl_->waiting_queue_);
+ bool more_handlers = impl_->locked_ = !impl_->ready_queue_.empty();
+ impl_->mutex_.unlock();
+
+ if (more_handlers)
+ io_context_impl_->post_immediate_completion(impl_, false);
+ }
+};
+
+void strand_service::do_dispatch(implementation_type& impl, operation* op)
{
// If we are running inside the io_context, and no other handler already
// holds the strand lock, then the handler can run immediately.
- bool can_dispatch = io_context_.can_dispatch();
+ bool can_dispatch = io_context_impl_.can_dispatch();
impl->mutex_.lock();
if (can_dispatch && !impl->locked_)
{
// Immediate invocation is allowed.
impl->locked_ = true;
impl->mutex_.unlock();
- return true;
+
+ // Indicate that this strand is executing on the current thread.
+ call_stack<strand_impl>::context ctx(impl);
+
+ // Ensure the next handler, if any, is scheduled on block exit.
+ on_dispatch_exit on_exit = { &io_context_impl_, impl };
+ (void)on_exit;
+
+ op->complete(&io_context_impl_, asio::error_code(), 0);
+ return;
}
if (impl->locked_)
@@ -117,10 +144,8 @@ bool strand_service::do_dispatch(implementation_type& impl, operation* op)
impl->locked_ = true;
impl->mutex_.unlock();
impl->ready_queue_.push(op);
- io_context_.post_immediate_completion(impl, false);
+ io_context_impl_.post_immediate_completion(impl, false);
}
-
- return false;
}
void strand_service::do_post(implementation_type& impl,
@@ -140,7 +165,7 @@ void strand_service::do_post(implementation_type& impl,
impl->locked_ = true;
impl->mutex_.unlock();
impl->ready_queue_.push(op);
- io_context_.post_immediate_completion(impl, is_continuation);
+ io_context_impl_.post_immediate_completion(impl, is_continuation);
}
}