Make the private op queue work with nested calls to poll() or poll_one().

This commit is contained in:
Christopher Kohlhoff 2011-10-04 22:07:40 +11:00
parent 9a66b5bf5e
commit b23fa4128e
2 changed files with 33 additions and 0 deletions

View File

@ -59,6 +59,19 @@ public:
call_stack<Key, Value>::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<Key, Value>;

View File

@ -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<std::size_t>::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);
}