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.
The whole yield / yield_hop dichotomy becomes much easier to read and explain
if we stick to a single yield_t class. Since the intention is for a consumer
to pass canonical instances rather than manipulating that class in any other
way, we can instantiate it however we want.
This gets rid of lots of ugly redundant boost::asio::handler_type<>
specializations.
Introduce yield_base with subclasses yield_t and yield_hop_t, each with a
canonical instance yield and yield_hop. yield_base adds allow_hop_ bool to
communicate the distinction to yield_handler: yield_t sets false, yield_hop_t
sets true.
Extract common base class yield_handler_base from yield_handler<T> and
yield_handler<void>. In fact yield_handler_base is almost identical to
yield_handler<void>; yield_handler<T> adds value processing.
Instead of capturing just the error_code* from the passed yield_base instance,
capture the whole yield_base: both its error_code* and the new allow_hop_ bool.
yield_handler_base provides operator()(error_code) method. This operator()
sets a new completed_ bool so calling fiber need NOT suspend if the async
operation completes immediately. That bool must be defended with a mutex.
This operator() also avoids migrating a pinned_context, or when a caller
passes plain yield instead of yield_hop.
New wait() method suspends the calling fiber only if (! completed_).
Extract common base class async_result_base from async_result<T> and
async_result<void>. In fact async_result_base is almost identical to
async_result<void>; async_result<T> adds value processing.
Add handler_type<> specializations for new yield_base and yield_hop_t
completion token types.
This covers both generic callbacks (adapt_callbacks.cpp,
adapt_method_calls.cpp) and custom Asio completion tokens (yield.hpp,
promise_completion_token.hpp, detail/yield.hpp, detail/promise_handler.hpp).
Mark up the relevant source files to provide code snippets for callbacks.qbk.
In essence, yield_t et al. become very like use_future_t et al. The only real
difference is the async_result return type and get() method. Factor out common
functionality into promise_completion_token and promise_handler.
Remove the boost::fibers::asio::spawn() function and its basic_yield_context
infrastructure. Fix up all existing references in example source code.