assert_excl_strand_ref

template<class T, class Strand = boost::asio::io_context::strand> class assert_excl_strand_ref; In coroutines the suspend point is clearly marked with await, which tells the reader that something unusual happens in this function and allows the reader, for example, to confirm whether the lifetimes of the objects of interest align with the lifetime of the coroutine or not, whether some locks need to be acquired to protect some concurrently accessed data, and whether some locks need to be released before the execution reaches the suspend point. [Read More]

condition_variable

template<class Strand> class basic_condition_variable; using condition_variable = basic_condition_variable<boost::asio::io_context::strand>; As in Boost.Fiber: The class condition_variable provides a mechanism for a fiber to wait for notification from another fiber. When the fiber awakens from the wait, then it checks to see if the appropriate condition is now true, and continues if so. If the condition is not true, then the fiber calls wait again to resume waiting. In the simplest case, this condition is just a boolean variable. [Read More]

fiber

class fiber; This class is a move-only handle representing a spawned fiber. fiber objects may also be in a state that doesn’t represent any fiber (default constructor, after move-from, detach(), or join()). Warning If the object represents a valid fiber, you MUST either call join(this_fiber) or detach() before the destructor is run. Important fiber is a typedef for basic_fiber<boost::asio::io_context::strand>. [Read More]

mutex

template<class Strand> class basic_mutex; using mutex = basic_mutex<boost::asio::io_context::strand>; As in Boost.Fiber: […​] synchronization objects can neither be moved nor copied. A synchronization object acts as a mutually-agreed rendezvous point between different fibers. If such an object were copied somewhere else, the new copy would have no consumers. If such an object were moved somewhere else, leaving the original instance in an unspecified state, existing consumers would behave strangely. [Read More]

scoped_fiber

struct detach; struct join_if_joinable; struct interrupt_and_join_if_joinable; template<class CallableFiber = join_if_joinable, class JoinerStrand = boost::asio::io_context::strand, class JoineeStrand = boost::asio::io_context::strand> class strict_scoped_fiber; template<class CallableFiber = join_if_joinable, class JoinerStrand = boost::asio::io_context::strand, class JoineeStrand = boost::asio::io_context::strand> class scoped_fiber; These wrappers have the same motivation in spirit as Boost.Thread: Scoped Threads are wrappers around a thread that allows the user to state what to do at destruction time. One of the common uses is to join the thread at destruction time so this is the default behavior. [Read More]

this_fiber

class fiber::this_fiber; To have access to a this_fiber object, just spawn a fiber and an object of this type will be created for you. You can copy and pass it around freely to other functions as you wish, but you should only use its methods within the fiber context (i.e. within the fiber execution stack) that created it. Important fiber is a typedef for basic_fiber<boost::asio::io_context::strand>. [Read More]

unique_lock

template<class Strand> class basic_unique_lock; using unique_lock = basic_unique_lock<boost::asio::io_context::strand>; template<class Strand> class basic_unique_lock { public: basic_unique_lock(basic_mutex<Strand>& mutex, typename basic_fiber<Strand>::this_fiber this_fiber) : mutex_(&mutex) , owns_lock_(true) { mutex_->lock(this_fiber); } basic_unique_lock(basic_unique_lock&& o) : mutex_(o.mutex_) , owns_lock_(o.owns_lock_) { o.mutex_ = nullptr; } basic_unique_lock& operator=(basic_unique_lock&& o) { if (mutex_ && owns_lock_) mutex_->unlock(); mutex_ = o.mutex_; owns_lock_ = o.owns_lock_; o.mutex_ = nullptr; return *this; } ~basic_unique_lock() { if (!mutex_) // moved return; if (owns_lock_) mutex_->unlock(); } void lock(typename basic_fiber<Strand>::this_fiber this_fiber) { if (! [Read More]