From f13c24bd6699a77e7d8f7c8bfacc7bd8f7284ee6 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Apr 2016 10:57:20 -0400 Subject: [PATCH 1/2] Launch client fibers on alternate thread. --- examples/asio/autoecho.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/examples/asio/autoecho.cpp b/examples/asio/autoecho.cpp index 0d3cb3c6..2f46d97c 100644 --- a/examples/asio/autoecho.cpp +++ b/examples/asio/autoecho.cpp @@ -236,19 +236,19 @@ int main( int argc, char* argv[]) { // server boost::fibers::fiber f( server, boost::ref( io_svc) ); - // client - const unsigned iterations = 20; - const unsigned clients = 3; - boost::fibers::barrier barrier(clients); - for (unsigned c = 0; c < clients; ++c) { - boost::fibers::fiber( - client, boost::ref( io_svc), boost::ref( barrier), - iterations ).detach(); - } // run io_service in two threads std::thread t([&io_svc](){ boost::fibers::use_scheduling_algorithm< boost::fibers::asio::round_robin >( io_svc); print( "Thread ", thread_names.lookup(), ": started"); + // client + const unsigned iterations = 20; + const unsigned clients = 3; + boost::fibers::barrier barrier(clients); + for (unsigned c = 0; c < clients; ++c) { + boost::fibers::fiber( + client, boost::ref( io_svc), boost::ref( barrier), + iterations ).detach(); + } io_svc.run(); print( "Thread ", thread_names.lookup(), ": stopping"); }); From 9b3559dd4946d82249bf3b857e1c78895161bb37 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 6 Apr 2016 12:03:30 -0400 Subject: [PATCH 2/2] Remove 'yield_hop' and the whole allow_hop_ mechanism. Given the necessity for fibers::asio::round_robin to share its ready queue among all threads calling io_service::run() on the same io_service instance, the capability to allow hop (or not) in the fibers::asio::yield mechanism is redundant. --- doc/callbacks.qbk | 4 ++-- examples/asio/detail/yield.hpp | 14 +++----------- examples/asio/yield.hpp | 17 +++++------------ 3 files changed, 10 insertions(+), 25 deletions(-) diff --git a/doc/callbacks.qbk b/doc/callbacks.qbk index 05e6760b..3788044e 100644 --- a/doc/callbacks.qbk +++ b/doc/callbacks.qbk @@ -184,7 +184,7 @@ and `future` for two reasons: `boost::fibers::asio::yield` is a completion token of this kind. `yield` is an instance of `yield_t`: -[fibers_asio_yield] +[fibers_asio_yield_t] `yield_t` is in fact only a placeholder, a way to trigger Boost.Asio customization. It can bind a @@ -195,7 +195,7 @@ for use by the actual handler. In fact there are two canonical instances of `yield_t` [mdash] `yield` and `yield_hop`: -[fibers_asio_yield_and_hop] +[fibers_asio_yield] We'll get to the differences between these shortly. diff --git a/examples/asio/detail/yield.hpp b/examples/asio/detail/yield.hpp index 29077c08..973673cb 100644 --- a/examples/asio/detail/yield.hpp +++ b/examples/asio/detail/yield.hpp @@ -87,18 +87,10 @@ public: * yt_.ec_ = ec; // If ctx_ is still active, e.g. because the async operation // immediately called its callback (this method!) before the asio - // async function called async_result_base::get(), we must neither - // migrate it nor set it ready. + // async function called async_result_base::get(), we must not set it + // ready. if ( fibers::context::active() != ctx_ ) { - // Are we permitted to wake up the suspended fiber on this thread, the - // thread that called the completion handler? - if ( ( ! ctx_->is_context( fibers::type::pinned_context) ) && yt_.allow_hop_) { - // We must not migrate a pinned_context to another thread. If this - // isn't a pinned_context, and the application passed yield_hop - // rather than yield, migrate this fiber to the running thread. - fibers::context::active()->migrate( ctx_); - } - // either way, wake the fiber + // wake the fiber fibers::context::active()->set_ready( ctx_); } } diff --git a/examples/asio/yield.hpp b/examples/asio/yield.hpp index 09e3aa63..b40f0295 100644 --- a/examples/asio/yield.hpp +++ b/examples/asio/yield.hpp @@ -18,12 +18,10 @@ namespace boost { namespace fibers { namespace asio { -//[fibers_asio_yield +//[fibers_asio_yield_t class yield_t { public: - yield_t( bool hop) : - allow_hop_( hop) { - } + yield_t() = default; /** * @code @@ -46,17 +44,12 @@ public: //private: // ptr to bound error_code instance if any boost::system::error_code * ec_{ nullptr }; - // allow calling fiber to "hop" to another thread if it could resume more - // quickly that way - bool allow_hop_; }; //] -//[fibers_asio_yield_and_hop -// canonical instance with allow_hop_ == false -thread_local yield_t yield{ false }; -// canonical instance with allow_hop_ == true -thread_local yield_t yield_hop{ true }; +//[fibers_asio_yield +// canonical instance +thread_local yield_t yield{}; //] }}}