From b23fa4128eb755f34df9187f073a239467e955cb Mon Sep 17 00:00:00 2001 From: Christopher Kohlhoff Date: Tue, 4 Oct 2011 22:07:40 +1100 Subject: [PATCH] Make the private op queue work with nested calls to poll() or poll_one(). --- asio/include/asio/detail/call_stack.hpp | 13 ++++++++++++ .../asio/detail/impl/task_io_service.ipp | 20 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/asio/include/asio/detail/call_stack.hpp b/asio/include/asio/detail/call_stack.hpp index 52ffa746..eb5278bd 100644 --- a/asio/include/asio/detail/call_stack.hpp +++ b/asio/include/asio/detail/call_stack.hpp @@ -59,6 +59,19 @@ public: call_stack::top_ = next_; } + // Find the next context with the same key. + Value* next_by_key() const + { + context* elem = next_; + while (elem) + { + if (elem->key_ == key_) + return elem->value_; + elem = elem->next_; + } + return 0; + } + private: friend class call_stack; diff --git a/asio/include/asio/detail/impl/task_io_service.ipp b/asio/include/asio/detail/impl/task_io_service.ipp index dc6ee5ac..b66462a2 100755 --- a/asio/include/asio/detail/impl/task_io_service.ipp +++ b/asio/include/asio/detail/impl/task_io_service.ipp @@ -192,6 +192,16 @@ std::size_t task_io_service::poll(asio::error_code& ec) mutex::scoped_lock lock(mutex_); +#if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + // We want to support nested calls to poll() and poll_one(), so any handlers + // that are already on a thread-private queue need to be put on to the main + // queue now. + if (one_thread_) + if (thread_info* outer_thread_info = ctx.next_by_key()) + if (outer_thread_info->private_op_queue) + op_queue_.push(*outer_thread_info->private_op_queue); +#endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + std::size_t n = 0; for (; do_poll_one(lock, private_op_queue, ec); lock.lock()) if (n != (std::numeric_limits::max)()) @@ -217,6 +227,16 @@ std::size_t task_io_service::poll_one(asio::error_code& ec) mutex::scoped_lock lock(mutex_); +#if defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + // We want to support nested calls to poll() and poll_one(), so any handlers + // that are already on a thread-private queue need to be put on to the main + // queue now. + if (one_thread_) + if (thread_info* outer_thread_info = ctx.next_by_key()) + if (outer_thread_info->private_op_queue) + op_queue_.push(*outer_thread_info->private_op_queue); +#endif // defined(BOOST_HAS_THREADS) && !defined(ASIO_DISABLE_THREADS) + return do_poll_one(lock, private_op_queue, ec); }