2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-02 20:52:21 +00:00
Files
fiber/doc/fibers.xml
2014-03-05 17:30:11 +01:00

7803 lines
486 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
<library id="fiber" name="Fiber" dirname="fiber" last-revision="$Date: 2014/02/22 19:01:43 $"
xmlns:xi="http://www.w3.org/2001/XInclude">
<libraryinfo>
<authorgroup>
<author>
<firstname>Oliver</firstname> <surname>Kowalke</surname>
</author>
</authorgroup>
<copyright>
<year>2013</year> <holder>Oliver Kowalke</holder>
</copyright>
<legalnotice id="fiber.legal">
<para>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at <ulink url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>)
</para>
</legalnotice>
<librarypurpose>
C++ Library to cooperatively schedule and synchronize micro-threads
</librarypurpose>
<librarycategory name="category:text"></librarycategory>
</libraryinfo>
<title>Fiber</title>
<section id="fiber.overview">
<title><link linkend="fiber.overview">Overview</link></title>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides a framework for micro-/userland-threads
(fibers) scheduled cooperatively. The API contains classes and functions to
manage and synchronize fibers similiarly to <ulink url="boost:/libs/thread/index.html">Boost.Thread</ulink>.
</para>
<para>
Each fiber has its own stack.
</para>
<para>
A fiber can save the current execution state, including all registers and CPU
flags, the instruction pointer, and the stack pointer and later restore this
state. The idea is to have multiple execution paths running on a single thread
using a sort of cooperative scheduling (versus threads, which are preemptively
scheduled). The running fiber decides explicitly when it should yield to allow
another fiber to run (context switching). <emphasis role="bold">Boost.Fiber</emphasis>
internally uses coroutines from <ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink>;
the classes in this library manage, schedule and, when needed, synchronize
those coroutines. A context switch between threads usually costs thousands
of CPU cycles on x86, compared to a fiber switch with a few hundred cycles.
A fiber can only run on a single thread at any point in time.
</para>
<para>
In order to use the classes and functions described here, you can either include
the specific headers specified by the descriptions of each class or function,
or include the master library header:
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
</programlisting>
<para>
which includes all the other headers in turn.
</para>
<para>
The namespaces used are:
</para>
<programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">this_fiber</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.overview.h0">
<phrase id="fiber.overview.fibers_and_threads"/><link linkend="fiber.overview.fibers_and_threads">Fibers
and Threads</link>
</bridgehead>
<para>
Control is cooperatively passed between fibers launched on a given thread.
At a given moment, on a given thread, at most one fiber is running.
</para>
<para>
Spawning additional fibers on a given thread does not increase your program's
utilization of hardware cores.
</para>
<para>
On the other hand, a fiber may safely access any resource exclusively owned
by its parent thread without explicitly needing to defend that resource against
concurrent access by other fibers on the same thread. You are already guaranteed
that no other fiber on that thread is concurrently touching that resource.
This can be particularly important when introducing concurrency in legacy code.
You can safely spawn fibers running old code, using asynchronous I/O to interleave
execution.
</para>
<para>
In effect, fibers provide a natural way to organize concurrent code based on
asynchronous I/O. Instead of chaining together completion handlers, code running
on a fiber can make what looks like a normal blocking function call. That call
can cheaply suspend the calling fiber, allowing other fibers on the same thread
to run. When the operation has completed, the suspended fiber resumes, without
having to explicitly save or restore its state. Its local stack variables persist
across the call.
</para>
<para>
A fiber launched on a particular thread will always run on that thread. A fiber
can count on thread-local storage; however that storage will be shared among
all fibers running on the same thread.
</para>
<para>
For fiber-local storage, please see <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link>.
</para>
<anchor id="blocking"/>
<bridgehead renderas="sect3" id="fiber.overview.h1">
<phrase id="fiber.overview.blocking"/><link linkend="fiber.overview.blocking">Blocking</link>
</bridgehead>
<para>
Normally, when this documentation states that a particular fiber <emphasis>blocks</emphasis>,
it means that it yields control, allowing other fibers on the same thread to
run. The synchronization mechanisms provided by <emphasis role="bold">Boost.Fiber</emphasis>
have this behavior.
</para>
<para>
A fiber may, of course, use normal thread synchronization mechanisms; however
a fiber that invokes any of these mechanisms will block its entire thread,
preventing any other fiber from running on that thread in the meantime. For
instance, when a fiber wants to wait for a value from another fiber in the
same thread, using <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">future</phrase></code> would be unfortunate: <code><phrase
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">future</phrase><phrase
role="special">::</phrase><phrase role="identifier">get</phrase><phrase role="special">()</phrase></code>
would block the whole thread, preventing the other fiber from delivering its
value. Use <link linkend="class_future"> <code>future&lt;&gt;</code></link> instead.
</para>
<para>
Similarly, a fiber that invokes a normal blocking I/O operation will block
its entire thread. Fiber authors are encouraged to consistently use asynchronous
I/O. <ulink url="boost:/libs/asio/index.html">Boost.Asio</ulink> explicitly
supports fibers; other asynchronous I/O operations can straightforwardly be
adapted for <emphasis role="bold">Boost.Fiber</emphasis>.
</para>
<para>
Synchronization between a fiber running on one thread and a fiber running on
a different thread is an advanced topic.
</para>
<warning>
<para>
This library is <emphasis>not</emphasis> an official Boost library
</para>
</warning>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> depends upon <ulink url="boost:/libs/chrono/index.html">Boost.Chrono</ulink>,
<ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink> and
<ulink url="boost:/libs/move/index.html">Boost.Move</ulink>. Boost version
1.55.0 or greater is required.
</para>
</section>
<section id="fiber.fiber_mgmt">
<title><link linkend="fiber.fiber_mgmt">Fiber management</link></title>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h0">
<phrase id="fiber.fiber_mgmt.synopsis"/><link linkend="fiber.fiber_mgmt.synopsis">Synopsis</link>
</bridgehead>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">all</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">boost</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">fibers</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&lt;(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber_group</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">algorithm</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">round_robin</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="identifier">algorithm</phrase> <phrase role="special">*</phrase> <phrase role="identifier">al</phrase><phrase role="special">)</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">this_fiber</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_point</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interruption_point</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_requested</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">disable_interruption</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">;</phrase>
<phrase role="special">}}</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h1">
<phrase id="fiber.fiber_mgmt.tutorial"/><link linkend="fiber.fiber_mgmt.tutorial">Tutorial</link>
</bridgehead>
<para>
Each <link linkend="class_fiber"> <code>fiber</code></link> represents a micro-thread which will be launched and managed
cooperatively by a scheduler. Objects of type <link linkend="class_fiber"> <code>fiber</code></link> are only moveable.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">;</phrase> <phrase role="comment">// not-a-fiber</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">f</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">);</phrase>
<phrase role="identifier">f1</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">f2</phrase><phrase role="special">);</phrase> <phrase role="comment">// f2 moved to f1</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h2">
<phrase id="fiber.fiber_mgmt.launching"/><link linkend="fiber.fiber_mgmt.launching">Launching</link>
</bridgehead>
<para>
A new fiber is launched by passing an object of a callable type that can be
invoked with no parameters. If the object must not (or cannot) be copied, then
<emphasis>boost::ref</emphasis> can be used to pass in a reference to the function
object. In this case, the user must ensure that the referenced object outlives
the newly-created fiber.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">callable</phrase>
<phrase role="special">{</phrase> <phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase> <phrase role="special">};</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">copies_are_safe</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">callable</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">x</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// x is destroyed, but the newly-created fiber has a copy, so this is OK</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">oops</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">callable</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">x</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// x is destroyed, but the newly-created fiber still has a reference</phrase>
<phrase role="comment">// this leads to undefined behaviour</phrase>
</programlisting>
<para>
Control is immediately transferred to the spawned <link linkend="class_fiber"> <code>fiber</code></link> at construction.
When the constructor returns, the <link linkend="class_fiber"> <code>fiber</code></link> might be complete or might
have suspended.
</para>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h3">
<phrase id="fiber.fiber_mgmt.exceptions"/><link linkend="fiber.fiber_mgmt.exceptions">Exceptions</link>
</bridgehead>
<para>
Exceptions thrown by the function or callable object passed to the <link linkend="class_fiber"> <code>fiber</code></link>
constructor
are consumed by the framework. If you need to know which exception was thrown,
use <link linkend="class_future"> <code>future&lt;&gt;</code></link> and <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link>.
</para>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h4">
<phrase id="fiber.fiber_mgmt.detaching"/><link linkend="fiber.fiber_mgmt.detaching">Detaching</link>
</bridgehead>
<para>
A <link linkend="class_fiber"> <code>fiber</code></link> can be detached by explicitly invoking the <link linkend="fiber_detach"> <code>fiber::detach()</code></link> member
function. After <link linkend="fiber_detach"> <code>fiber::detach()</code></link> is called on a fiber object, that
object represents <emphasis>not-a-fiber</emphasis>. The fiber object may then
safely be destroyed.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">).</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h5">
<phrase id="fiber.fiber_mgmt.joining"/><link linkend="fiber.fiber_mgmt.joining">Joining</link>
</bridgehead>
<para>
In order to wait for a fiber to finish, the <link linkend="fiber_join"> <code>fiber::join()</code></link> member function
of the <link linkend="class_fiber"> <code>fiber</code></link> object can be used. <link linkend="fiber_join"> <code>fiber::join()</code></link> will block
until the <link linkend="class_fiber"> <code>fiber</code></link> object has completed. If the <link linkend="class_fiber"> <code>fiber</code></link> has
already completed, or the <link linkend="class_fiber"> <code>fiber</code></link> object represents <emphasis>not-a-fiber</emphasis>,
then <link linkend="fiber_join"> <code>fiber::join()</code></link> returns immediately.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase> <phrase role="special">...</phrase> <phrase role="special">}</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">);</phrase>
<phrase role="special">...</phrase>
<phrase role="identifier">f</phrase><phrase role="special">.</phrase><phrase role="identifier">join</phrase><phrase role="special">();</phrase>
</programlisting>
<para>
If the fiber has already completed, then <link linkend="fiber_join"> <code>fiber::join()</code></link> returns immediately
and the joined <link linkend="class_fiber"> <code>fiber</code></link> object becomes <emphasis>not-a-fiber</emphasis>.
</para>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h6">
<phrase id="fiber.fiber_mgmt.destruction"/><link linkend="fiber.fiber_mgmt.destruction">Destruction</link>
</bridgehead>
<para>
When a <link linkend="class_fiber"> <code>fiber</code></link> object representing a valid execution context is destroyed,
the program terminates if the fiber is <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>. If
you intend the fiber to outlive the <link linkend="class_fiber"> <code>fiber</code></link> object that launched it,
use the <link linkend="fiber_detach"> <code>fiber::detach()</code></link>
method.
</para>
<programlisting><phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// std::terminate() will be called</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase><phrase role="identifier">some_fn</phrase><phrase role="special">);</phrase>
<phrase role="identifier">f</phrase><phrase role="special">.</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// okay, program continues</phrase>
</programlisting>
<anchor id="interruption"/>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h7">
<phrase id="fiber.fiber_mgmt.interruption"/><link linkend="fiber.fiber_mgmt.interruption">Interruption</link>
</bridgehead>
<para>
A valid fiber can be interrupted by invoking its <link linkend="fiber_interrupt"> <code>fiber::interrupt()</code></link> member
function. The next time that fiber executes one of the specific <link linkend="interruption"><emphasis>interruption-points</emphasis></link>
with interruption enabled, a <code><phrase role="identifier">fiber_interrupted</phrase></code>
exception will be thrown. If this exception is not caught, the fiber will be
terminated, its stack unwound, its stack objects properly destroyed.
</para>
<para>
With <link linkend="class_disable_interruption"> <code>disable_interruption</code></link> a fiber can avoid being
interrupted.
</para>
<programlisting><phrase role="comment">// interruption enabled at this point</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">disable_interruption</phrase> <phrase role="identifier">di1</phrase><phrase role="special">;</phrase>
<phrase role="comment">// interruption disabled</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="keyword">this</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">disable_interruption</phrase> <phrase role="identifier">di2</phrase><phrase role="special">;</phrase>
<phrase role="comment">// interruption still disabled</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// di2 destroyed; interruption state restored</phrase>
<phrase role="comment">// interruption still disabled</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// di destroyed; interruption state restored</phrase>
<phrase role="comment">// interruption enabled</phrase>
</programlisting>
<para>
At any point, the interruption state for the current thread can be queried
by calling <link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link>.
The following <link linkend="interruption"><emphasis>interruption-points</emphasis></link>
are defined and will throw <code><phrase role="identifier">fiber_interrupted</phrase></code>
if <link linkend="this_fiber_interruption_requested"> <code>this_fiber::interruption_requested()</code></link> and
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link>.
</para>
<itemizedlist>
<listitem>
<simpara>
<link linkend="fiber_join"> <code>fiber::join()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="barrier_wait"> <code>barrier::wait()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="condition_variable_wait"> <code>condition_variable::wait()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="condition_variable_wait_for"> <code>condition_variable::wait_for()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="condition_variable_wait_until"> <code>condition_variable::wait_until()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="this_fiber_sleep_for"> <code>this_fiber::sleep_for()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="this_fiber_sleep_until"> <code>this_fiber::sleep_until()</code></link>
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="this_fiber_interruption_point"> <code>this_fiber::interruption_point()</code></link>
</simpara>
</listitem>
</itemizedlist>
<anchor id="class_fiber_id"/>
<bridgehead renderas="sect3" id="fiber.fiber_mgmt.h8">
<phrase id="fiber.fiber_mgmt.fiber_ids"/><link linkend="fiber.fiber_mgmt.fiber_ids">Fiber
IDs</link>
</bridgehead>
<para>
Objects of class <link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code></link> can be
used to identify fibers. Each running <link linkend="class_fiber"> <code>fiber</code></link> has a unique <link linkend="class_fiber_id"><code><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase></code></link> obtainable
from the corresponding <link linkend="class_fiber"> <code>fiber</code></link>
by calling the <link linkend="fiber_get_id"> <code>fiber::get_id()</code></link> member
function. Objects of class <link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code></link> can be
copied, and used as keys in associative containers: the full range of comparison
operators is provided. They can also be written to an output stream using the
stream insertion operator, though the output format is unspecified.
</para>
<para>
Each instance of <link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code></link> either
refers to some fiber, or <emphasis>not-a-fiber</emphasis>. Instances that refer
to <emphasis>not-a-fiber</emphasis> compare equal to each other, but not equal
to any instances that refer to an actual fiber. The comparison operators on
<link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code></link> yield a total order for every non-equal
<link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code></link>.
</para>
<section id="fiber.fiber_mgmt.fiber">
<title><anchor id="class_fiber"/><link linkend="fiber.fiber_mgmt.fiber">Class
<code><phrase role="identifier">fiber</phrase></code></link></title>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">uspecified</phrase><phrase role="special">-</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">id</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">stack_allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">joinable</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">priority</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">detach</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">join</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interrupt</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&lt;(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h0">
<phrase id="fiber.fiber_mgmt.fiber.default_constructor"/><link linkend="fiber.fiber_mgmt.fiber.default_constructor">Default
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs a <link linkend="class_fiber"> <code>fiber</code></link> instance that refers to <emphasis>not-a-fiber</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase><phrase
role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h1">
<phrase id="fiber.fiber_mgmt.fiber.constructor"/><link linkend="fiber.fiber_mgmt.fiber.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">stack_allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">Fn</phrase></code> must be copyable
or movable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
<code><phrase role="identifier">fn</phrase></code> is copied into internal
storage for access by the new fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to the newly created fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> if
an error occurs.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
StackAllocator is required to allocate a stack for the internal coroutine.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h2">
<phrase id="fiber.fiber_mgmt.fiber.move_constructor"/><link linkend="fiber.fiber_mgmt.fiber.move_constructor">Move
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Transfers ownership of the fiber managed by <code><phrase role="identifier">other</phrase></code>
to the newly constructed <link linkend="class_fiber"> <code>fiber</code></link> instance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase></code> returns the value of <code><phrase
role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>
prior to the construction
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h3">
<phrase id="fiber.fiber_mgmt.fiber.move_assignment_operator"/><link linkend="fiber.fiber_mgmt.fiber.move_assignment_operator">Move
assignment operator</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Transfers ownership of the fiber managed by <code><phrase role="identifier">other</phrase></code>
(if any) to <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase></code> returns the value of <code><phrase
role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>
prior to the assignment.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h4">
<phrase id="fiber.fiber_mgmt.fiber.destructor"/><link linkend="fiber.fiber_mgmt.fiber.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If the fiber is <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>, calls std::terminate.
Destroys <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The programmer must ensure that the destructor is never executed while
the fiber is still <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>. Even if you know
(by calling <link linkend="fiber_operator safe_bool"> <code>fiber::operator safe_bool()</code></link>) that
the fiber has completed, you must still call either <link linkend="fiber_join"> <code>fiber::join()</code></link> or
<link linkend="fiber_detach"> <code>fiber::detach()</code></link> before destroying the <code><phrase role="identifier">fiber</phrase></code>
object.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_joinable_bridgehead">
<phrase id="fiber_joinable"/>
<link linkend="fiber_joinable">Member function <code>joinable</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">joinable</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution, which may or may not have completed;
otherwise <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="fiber_operator safe_bool"> <code>fiber::operator safe_bool()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_join_bridgehead">
<phrase id="fiber_join"/>
<link linkend="fiber_join">Member function <code>join</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">join</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
the fiber is <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution, waits for that fiber to complete.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution on entry, that fiber has completed.
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
no longer refers to any fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code> if
the current fiber is interrupted or <code><phrase role="identifier">system_error</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Error Conditions:</term>
<listitem>
<para>
<emphasis role="bold">resource_deadlock_would_occur</emphasis>: if
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">this_fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase></code>. <emphasis role="bold">invalid_argument</emphasis>:
if the fiber is not <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Notes:</term>
<listitem>
<para>
<code><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
is one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_detach_bridgehead">
<phrase id="fiber_detach"/>
<link linkend="fiber_detach">Member function <code>detach</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">detach</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
the fiber is <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The fiber of execution becomes detached, and no longer has an associated
<link linkend="class_fiber"> <code>fiber</code></link> object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
no longer refers to any fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">system_error</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Error Conditions:</term>
<listitem>
<para>
<emphasis role="bold">invalid_argument</emphasis>: if the fiber is
not <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_get_id_bridgehead">
<phrase id="fiber_get_id"/>
<link linkend="fiber_get_id">Member function <code>get_id</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution, an instance of <link linkend="class_fiber_id"><code><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code></link> that represents that fiber. Otherwise
returns a default-constructed <link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="this_fiber_get_id"> <code>this_fiber::get_id()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_interrupt_bridgehead">
<phrase id="fiber_interrupt"/>
<link linkend="fiber_interrupt">Member function <code>interrupt</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">interrupt</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution, request that the fiber will be interrupted
the next time it enters one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>
with interruption enabled, or if it is currently <link linkend="blocking"><emphasis>blocked</emphasis></link>
in a call to one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>
with interruption enabled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h5">
<phrase id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special_____phrase___phrase_role__keyword__int__phrase__phrase_role__special_____phrase___code_"/><link
linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special_____phrase___phrase_role__keyword__int__phrase__phrase_role__special_____phrase___code_">Member
function <code><phrase role="identifier">priority</phrase><phrase role="special">(</phrase>
<phrase role="keyword">int</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
set priority for the fiber referenced by <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The meaning of particular <code><phrase role="keyword">int</phrase></code>
values is determined by the specific <link linkend="class_algorithm"> <code>algorithm</code></link> passed
to <link linkend="set_scheduling_algorithm"> <code>set_scheduling_algorithm()</code></link>. <link linkend="class_round_robin"> <code>round_robin</code></link> and
<link linkend="class_round_robin_ws"> <code>round_robin_ws</code></link> ignore <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">priority</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_priority_bridgehead">
<phrase id="fiber_priority"/>
<link linkend="fiber_priority">Member function <code>priority</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">priority</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
priority for the fiber referenced by <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber_thread_affinity"/>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h6">
<phrase id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__thread_affinity__phrase__phrase_role__special_____phrase___phrase_role__keyword__bool__phrase__phrase_role__special_____phrase___code_"/><link
linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__thread_affinity__phrase__phrase_role__special_____phrase___phrase_role__keyword__bool__phrase__phrase_role__special_____phrase___code_">Member
function <code><phrase role="identifier">thread_affinity</phrase><phrase
role="special">(</phrase> <phrase role="keyword">bool</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Set thread affinity for the fiber referenced by <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
&quot;Thread affinity&quot; is only meaningful for certain scheduler
algorithms, such as <link linkend="class_round_robin_ws"> <code>round_robin_ws</code></link>. Many schedulers
ignore this fiber attribute. With a scheduler that might potentially
migrate a fiber from its initial thread to another, the value <code><phrase
role="keyword">true</phrase></code> prevents migration: the fiber will
always run on its current thread. The default is <code><phrase role="keyword">false</phrase></code>:
normally, with an applicable scheduler, a fiber is allowed to migrate
across threads.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="this_fiber_thread_affinity"> <code>this_fiber::thread_affinity()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h7">
<phrase id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__thread_affinity__phrase__phrase_role__special______phrase___code_"/><link
linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__thread_affinity__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">thread_affinity</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
thread affinity for the fiber referenced by <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="this_fiber_thread_affinity"> <code>this_fiber::thread_affinity()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_operator safe_bool_bridgehead">
<phrase id="fiber_operator safe_bool"/>
<link linkend="fiber_operator
safe_bool">Member function <code>operator safe_bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to a fiber of execution which has not yet terminated, <code><phrase
role="keyword">false</phrase></code> otherwise. Compare to <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>,
which does not distinguish whether the referenced fiber of execution
is still running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_operator_not_bridgehead">
<phrase id="fiber_operator_not"/>
<link linkend="fiber_operator_not">Member function
<code>operator!</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
does not refer to a fiber of execution or if its fiber of execution
has terminated, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="fiber_operator safe_bool"> <code>fiber::operator safe_bool()</code></link>, <link linkend="fiber_joinable"> <code>fiber::joinable()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_swap_bridgehead">
<phrase id="fiber_swap"/>
<link linkend="fiber_swap">Member function <code>swap</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Exchanges the fiber of execution associated with <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> and <code><phrase role="identifier">other</phrase></code>,
so <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
becomes associated with the fiber formerly associated with <code><phrase
role="identifier">other</phrase></code>, and vice-versa.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>
returns the same value as <code><phrase role="identifier">other</phrase><phrase
role="special">.</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase></code> prior to the call. <code><phrase
role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>
returns the same value as <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase></code> prior to the call.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="swap_bridgehead">
<phrase id="swap"/>
<link linkend="swap">Non-member function <code>swap()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Same as <code><phrase role="identifier">l</phrase><phrase role="special">.</phrase><phrase
role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase
role="identifier">r</phrase><phrase role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="set_scheduling_algorithm_bridgehead">
<phrase id="set_scheduling_algorithm"/>
<link linkend="set_scheduling_algorithm">Non-member
function <code>set_scheduling_algorithm()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="identifier">algorithm</phrase><phrase role="special">*</phrase> <phrase role="identifier">scheduler</phrase> <phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Directs <emphasis role="bold">Boost.Fiber</emphasis> to use <code><phrase
role="identifier">scheduler</phrase></code>, which must be a concrete
subclass of <link linkend="class_algorithm"> <code>algorithm</code></link>, as the scheduling algorithm for
all fibers in the current thread.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Previous <link linkend="class_algorithm"> <code>algorithm</code></link> instance set for the current thread,
0 if this is the first <emphasis role="bold">Boost.Fiber</emphasis>
entry point called by the current thread.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
If you want a given thread to use a non-default scheduling algorithm,
make that thread call <code><phrase role="identifier">set_scheduling_algorithm</phrase><phrase
role="special">()</phrase></code> before any other <emphasis role="bold">Boost.Fiber</emphasis>
entry point. If no scheduler has been set for the current thread by
the time <emphasis role="bold">Boost.Fiber</emphasis> needs to use
it, the library will heap-allocate a default <link linkend="class_round_robin"> <code>round_robin</code></link> instance
for this thread.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">set_scheduling_algorithm</phrase><phrase
role="special">()</phrase></code> does <emphasis>not</emphasis> take
ownership of the passed <code><phrase role="identifier">algorithm</phrase><phrase
role="special">*</phrase></code>: <emphasis role="bold">Boost.Fiber</emphasis>
does not claim responsibility for the lifespan of the referenced <code><phrase
role="identifier">scheduler</phrase></code> object. The caller must
eventually destroy the passed <code><phrase role="identifier">scheduler</phrase></code>,
just as it must allocate it in the first place. (Storing the pointer
in a <code><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
role="identifier">thread_specific_ptr</phrase></code> is one way to
ensure that the instance is destroyed on thread termination.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.fiber_mgmt.fiber_group">
<title><anchor id="class_fiber_group"/><link linkend="fiber.fiber_mgmt.fiber_group">Class
<code><phrase role="identifier">fiber_group</phrase></code></link></title>
<para>
<link linkend="class_fiber_group"> <code>fiber_group</code></link> represents a collection of fibers which can be
collectively waited on or interrupted. <link linkend="class_fiber_group"> <code>fiber_group</code></link> is neither
copyable nor movable.
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber_group</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">fiber_group</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="special">~</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
<phrase role="identifier">fiber_group</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_group</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber_group</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber_group</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_fiber_in</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">remove_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">join_all</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interrupt_all</phrase><phrase role="special">();</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber_group.h0">
<phrase id="fiber.fiber_mgmt.fiber_group.constructor"/><link linkend="fiber.fiber_mgmt.fiber_group.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Create a new fiber group with no fibers.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber_group.h1">
<phrase id="fiber.fiber_mgmt.fiber_group.destructor"/><link linkend="fiber.fiber_mgmt.fiber_group.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroy <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
and all <link linkend="class_fiber"> <code>fiber</code></link> objects in the group.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_create_fiber_bridgehead">
<phrase id="fiber_group_create_fiber"/>
<link linkend="fiber_group_create_fiber">Member
function <code>create_fiber</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Create a new <link linkend="class_fiber"> <code>fiber</code></link> object as-if by <code><phrase role="keyword">new</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">(</phrase>
<phrase role="identifier">fn</phrase><phrase role="special">)</phrase></code>
and add it to the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is increased by one, the new fiber is running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A pointer to the new <link linkend="class_fiber"> <code>fiber</code></link> object.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_add_fiber_bridgehead">
<phrase id="fiber_group_add_fiber"/>
<link linkend="fiber_group_add_fiber">Member
function <code>add_fiber</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
The expression <code><phrase role="keyword">delete</phrase> <phrase
role="identifier">f</phrase></code> is well-formed and will not result
in undefined behaviour and <code><phrase role="identifier">is_fiber_in</phrase><phrase
role="special">(</phrase><phrase role="identifier">f</phrase><phrase
role="special">)</phrase> <phrase role="special">==</phrase> <phrase
role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Add <link linkend="class_fiber"> <code>fiber</code></link> object pointed to by <code><phrase role="identifier">f</phrase></code>
to the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is increased by one.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Unless the same <code><phrase role="identifier">f</phrase></code> is
later passed to <code><phrase role="identifier">remove_fiber</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> becomes responsible for the lifespan
of <code><phrase role="special">*</phrase><phrase role="identifier">f</phrase></code>.
When the <code><phrase role="identifier">fiber_group</phrase></code>
is destroyed, <code><phrase role="special">*</phrase><phrase role="identifier">f</phrase></code>
will also be destroyed.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
The Precondition implies that <code><phrase role="identifier">f</phrase></code>
must point to a heap <link linkend="class_fiber"> <code>fiber</code></link> object. This is erroneous:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber_group</phrase> <phrase role="identifier">fg</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase><phrase role="identifier">somefunc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">fg</phrase><phrase role="special">.</phrase><phrase role="identifier">add_fiber</phrase><phrase role="special">(&amp;</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// WRONG!</phrase>
</programlisting>
<para>
Instead, use the following:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber_group</phrase> <phrase role="identifier">fg</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">*</phrase> <phrase role="identifier">f</phrase> <phrase role="special">=</phrase> <phrase role="keyword">new</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">somefunc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">fg</phrase><phrase role="special">.</phrase><phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// okay, fg is now responsible for *f</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="fiber_group_remove_fiber_bridgehead">
<phrase id="fiber_group_remove_fiber"/>
<link linkend="fiber_group_remove_fiber">Member
function <code>remove_fiber</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">remove_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="identifier">f</phrase></code> is a member of
the group, remove it without calling <code><phrase role="keyword">delete</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
If <code><phrase role="identifier">f</phrase></code> was a member of
the group, <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is decreased by one.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_join_all_bridgehead">
<phrase id="fiber_group_join_all"/>
<link linkend="fiber_group_join_all">Member
function <code>join_all</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">join_all</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Requires:</term>
<listitem>
<para>
<code><phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Call <code><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
on each <link linkend="class_fiber"> <code>fiber</code></link> object in the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
Every fiber in the group has terminated.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Since <link linkend="fiber_join"> <code>fiber::join()</code></link> is one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>,
<code><phrase role="identifier">join_all</phrase><phrase role="special">()</phrase></code>
is also an interruption point.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_is_this_fiber_in_bridgehead">
<phrase id="fiber_group_is_this_fiber_in"/>
<link linkend="fiber_group_is_this_fiber_in">Member
function <code>is_this_fiber_in</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
true if there is a fiber <code><phrase role="identifier">f</phrase></code>
in the group such that <code><phrase role="identifier">f</phrase><phrase
role="special">.</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase> <phrase role="special">==</phrase> <phrase
role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_is_fiber_in_bridgehead">
<phrase id="fiber_group_is_fiber_in"/>
<link linkend="fiber_group_is_fiber_in">Member
function <code>is_fiber_in</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_fiber_in</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
true if there is a fiber <code><phrase role="identifier">fx</phrase></code>
in the group such that <code><phrase role="identifier">fx</phrase><phrase
role="special">.</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase> <phrase role="special">==</phrase> <phrase
role="identifier">f</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_interrupt_all_bridgehead">
<phrase id="fiber_group_interrupt_all"/>
<link linkend="fiber_group_interrupt_all">Member
function <code>interrupt_all</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">interrupt_all</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Call <code><phrase role="identifier">interrupt</phrase><phrase role="special">()</phrase></code>
on each <link linkend="class_fiber"> <code>fiber</code></link> object in the group.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_group_size_bridgehead">
<phrase id="fiber_group_size"/>
<link linkend="fiber_group_size">Member function
<code>size</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">size</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The number of fibers in the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.fiber_mgmt.attributes">
<title><anchor id="class_attributes"/><link linkend="fiber.fiber_mgmt.attributes">Class
attributes</link></title>
<para>
Class <code><phrase role="identifier">attributes</phrase></code> is used
to transfer parameters required to set up a fiber's context.
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">attributes</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">attributes</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.attributes.h0">
<phrase id="fiber.fiber_mgmt.attributes.constructor"/><link linkend="fiber.fiber_mgmt.attributes.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">attributes</phrase><phrase role="special">();</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Parameter <code><phrase role="identifier">size</phrase></code> determines
the stack size.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.fiber_mgmt.this_fiber">
<title><link linkend="fiber.fiber_mgmt.this_fiber">Namespace this_fiber</link></title>
<programlisting><phrase role="keyword">namespace</phrase> <phrase role="identifier">boost</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">this_fiber</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sleep_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">req</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interruption_point</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_requested</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">disable_interruption</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">;</phrase>
<phrase role="special">}}</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="this_fiber_get_id_bridgehead">
<phrase id="this_fiber_get_id"/>
<link linkend="this_fiber_get_id">Non-member
function <code>this_fiber::get_id()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
An instance of <link linkend="class_fiber_id"><code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code></link> that
represents the currently executing fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_sleep_until_bridgehead">
<phrase id="this_fiber_sleep_until"/>
<link linkend="this_fiber_sleep_until">Non-member
function <code>this_fiber::sleep_until()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">abs_time</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends the current fiber until the time point specified by <code><phrase
role="identifier">abs_time</phrase></code> has been reached.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code> if
the current fiber is interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">sleep_until</phrase><phrase role="special">()</phrase></code>
is one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The current fiber will not resume before <code><phrase role="identifier">abs_time</phrase></code>,
but there are no guarantees about how soon after <code><phrase role="identifier">abs_time</phrase></code>
it might resume.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_sleep_for_bridgehead">
<phrase id="this_fiber_sleep_for"/>
<link linkend="this_fiber_sleep_for">Non-member
function <code>this_fiber::sleep_for()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">rel_time</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends the current fiber until the time duration specified by <code><phrase
role="identifier">rel_time</phrase></code> has elapsed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing if operations of chrono::duration&lt;Rep, Period&gt; do not
throw exceptions. <code><phrase role="identifier">fiber_interrupted</phrase></code>
if the current fiber is interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">sleep_for</phrase><phrase role="special">()</phrase></code>
is one of the predefined <link linkend="interruption"><emphasis>interruption-points</emphasis></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The current fiber will not resume before <code><phrase role="identifier">rel_time</phrase></code>
has elapsed, but there are no guarantees about how soon after that
it might resume.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_yield_bridgehead">
<phrase id="this_fiber_yield"/>
<link linkend="this_fiber_yield">Non-member function
<code>this_fiber::yield()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Reliquishes execution control, allowing other fibers to run.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_resource_error</phrase></code>
if an error occurs.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_thread_affinity_bridgehead">
<phrase id="this_fiber_thread_affinity"/>
<link linkend="this_fiber_thread_affinity">Non-member
function <code>this_fiber::thread_affinity()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">thread_affinity</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">req</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Set or report <link linkend="fiber_thread_affinity"> <code>fiber::thread_affinity()</code></link> for the
currently running fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<link linkend="fiber_thread_affinity"> <code>fiber::thread_affinity()</code></link> is <code><phrase role="keyword">false</phrase></code>
by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_interruption_point_bridgehead">
<phrase id="this_fiber_interruption_point"/>
<link linkend="this_fiber_interruption_point">Non-member
function <code>this_fiber::interruption_point()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
</programlisting>
<para>
void interruption_point();
</para>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Check to see if the current fiber has been interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code> if
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> and
<link linkend="this_fiber_interruption_requested"> <code>this_fiber::interruption_requested()</code></link> both
return <code><phrase role="keyword">true</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_interruption_requested_bridgehead">
<phrase id="this_fiber_interruption_requested"/>
<link linkend="this_fiber_interruption_requested">Non-member
function <code>this_fiber::interruption_requested()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_requested</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if interruption has
been requested for the current fiber, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="this_fiber_interruption_enabled_bridgehead">
<phrase id="this_fiber_interruption_enabled"/>
<link linkend="this_fiber_interruption_enabled">Non-member
function <code>this_fiber::interruption_enabled()</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if interruption is
enabled for the current fiber, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Interruption is enabled by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_disable_interruption_bridgehead">
<phrase id="class_disable_interruption"/>
<link linkend="class_disable_interruption">Class
<code>disable_interruption</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">disable_interruption</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">disable_interruption</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">disable_interruption</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">disable_interruption</phrase><phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">disable_interruption</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.this_fiber.h0">
<phrase id="fiber.fiber_mgmt.this_fiber.constructor"/><link linkend="fiber.fiber_mgmt.this_fiber.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Stores the current state of <link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> and
disables interruption for the current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> returns
<code><phrase role="keyword">false</phrase></code> for the current
fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.this_fiber.h1">
<phrase id="fiber.fiber_mgmt.this_fiber.destructor"/><link linkend="fiber.fiber_mgmt.this_fiber.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
Must be called from the same fiber on which <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> was constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Restores the state of <link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> for
the current fiber to the state saved at construction of <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> for
the current fiber returns the value stored by the constructor of <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_restore_interruption_bridgehead">
<phrase id="class_restore_interruption"/>
<link linkend="class_restore_interruption">Class
<code>restore_interruption</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">restore_interruption</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">(</phrase><phrase role="identifier">disable_interruption</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">disabler</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">restore_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">restore_interruption</phrase><phrase role="special">(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">restore_interruption</phrase><phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase><phrase role="keyword">const</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.this_fiber.h2">
<phrase id="fiber.fiber_mgmt.this_fiber.constructor0"/><link linkend="fiber.fiber_mgmt.this_fiber.constructor0">Constructor</link>
</bridgehead>
<programlisting><phrase role="keyword">explicit</phrase> <phrase role="identifier">restore_interruption</phrase><phrase role="special">(</phrase><phrase role="identifier">disable_interruption</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">disabler</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
Must be called from the same fiber on which <code><phrase role="identifier">disabler</phrase></code>
was constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Restores the current state of <link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> for
the current fiber to that saved in <code><phrase role="identifier">disabler</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> for
the current fiber returns the value stored in the constructor of <code><phrase
role="identifier">disabler</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.this_fiber.h3">
<phrase id="fiber.fiber_mgmt.this_fiber.destructor0"/><link linkend="fiber.fiber_mgmt.this_fiber.destructor0">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">restore_interruption</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
Must be called from the same fiber on which <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> was constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Disables interruption for the current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<link linkend="this_fiber_interruption_enabled"> <code>this_fiber::interruption_enabled()</code></link> for
the current fiber returns <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">foo</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="comment">// interruption is enabled</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">disable_interruption</phrase> <phrase role="identifier">di</phrase><phrase role="special">;</phrase>
<phrase role="comment">// interruption is disabled</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">restore_interruption</phrase> <phrase role="identifier">ri</phrase><phrase role="special">(</phrase> <phrase role="identifier">di</phrase><phrase role="special">);</phrase>
<phrase role="comment">// interruption now enabled</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// ri destroyed, interruption disable again</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// di destructed, interruption state restored</phrase>
<phrase role="comment">// interruption now enabled</phrase>
<phrase role="special">}</phrase>
</programlisting>
</section>
</section>
<section id="fiber.scheduling">
<title><link linkend="fiber.scheduling">Scheduling</link></title>
<para>
Fibers are managed by a scheduler which coordinates the sequence of fibers
running or waiting. Each thread is required to have its own scheduler. By default,
<emphasis role="bold">Boost.Fiber</emphasis> allocates for each thread a scheduler
( <link linkend="class_round_robin"> <code>round_robin</code></link>) on the heap. To prevent the library from heap-allocating
a default scheduler for a given thread, that thread must call <link linkend="set_scheduling_algorithm"> <code>set_scheduling_algorithm()</code></link> before
any other <emphasis role="bold">Boost.Fiber</emphasis> entry point.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">thread_fn</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">my_fiber_scheduler</phrase> <phrase role="identifier">mfs</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">mfs</phrase><phrase role="special">);</phrase>
<phrase role="special">...</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
A fiber-scheduler must implement interface <link linkend="class_algorithm"> <code>algorithm</code></link>. <emphasis
role="bold">Boost.Fiber</emphasis> provides two schedulers: <link linkend="class_round_robin"> <code>round_robin</code></link> and
<link linkend="class_round_robin_ws"> <code>round_robin_ws</code></link>.
</para>
<para>
You are explicitly permitted to code your own <link linkend="class_algorithm"> <code>algorithm</code></link> subclass,
and to pass it to <link linkend="set_scheduling_algorithm"> <code>set_scheduling_algorithm()</code></link>.
</para>
<para>
<bridgehead renderas="sect4" id="class_algorithm_bridgehead">
<phrase id="class_algorithm"/>
<link linkend="class_algorithm">Class <code>algorithm</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">algorithm</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">algorithm</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="special">~</phrase><phrase role="identifier">algorithm</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="identifier">algorithm</phrase><phrase role="special">(</phrase> <phrase role="identifier">algorithm</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">algorithm</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">algorithm</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">spawn</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;,</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">join</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;,</phrase>
<phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;,</phrase>
<phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_main_id</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">notify</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">get_main_fiber</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="identifier">algorithm</phrase> <phrase role="special">*);</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="algorithm_spawn_bridgehead">
<phrase id="algorithm_spawn"/>
<link linkend="algorithm_spawn">Member function <code>spawn</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">spawn</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Spawns fiber <code><phrase role="identifier">f</phrase></code>, e.g.
<code><phrase role="identifier">f</phrase></code> will be entered the
first time or resumed where it was suspended before. Suspends the current
fiber.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_priority_bridgehead">
<phrase id="algorithm_priority"/>
<link linkend="algorithm_priority">Member function
<code>priority</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">f</phrase><phrase role="special">,</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">p</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Sets priority <code><phrase role="identifier">p</phrase></code> for fiber
<code><phrase role="identifier">f</phrase></code>. Interpretation of
&quot;priority&quot; is entirely up to the subclass.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_join_bridgehead">
<phrase id="algorithm_join"/>
<link linkend="algorithm_join">Member function <code>join</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">join</phrase><phrase role="special">(</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends the current fiber until fiber <code><phrase role="identifier">f</phrase></code>
terminates.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_active_bridgehead">
<phrase id="algorithm_active"/>
<link linkend="algorithm_active">Member function
<code>active</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The active fiber, or a null-pointer if the current execution context
is not a fiber managed by this <link linkend="class_algorithm"> <code>algorithm</code></link> instance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
While the initial context for a given thread is conceptually also a fiber,
it has no associated <code><phrase role="identifier">detail</phrase><phrase
role="special">::</phrase><phrase role="identifier">worker_fiber</phrase></code>
instance. This is when <code><phrase role="identifier">active</phrase><phrase
role="special">()</phrase></code> returns null. Higher-level <emphasis
role="bold">Boost.Fiber</emphasis> operations treat a thread's initial
context as equivalent to an explicitly-launched fiber, but this method
operates below that level of abstraction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="algorithm_get_main_id"> <code>algorithm::get_main_id()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_run_bridgehead">
<phrase id="algorithm_run"/>
<link linkend="algorithm_run">Member function <code>run</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">run</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Selects one fiber in ready state and runs it until it suspends. The choice
of fiber is up to the subclass instance.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if one fiber
was ready and successfully executed, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_wait_bridgehead">
<phrase id="algorithm_wait"/>
<link linkend="algorithm_wait">Member function <code>wait</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the current
fiber. It locks the spinlock protecting the internal state of a mutex
or condition_variable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Current fiber is set to waiting-state and gets suspended.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is unlocked.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_wait_until_bridgehead">
<phrase id="algorithm_wait_until"/>
<link linkend="algorithm_wait_until">Member
function <code>wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">,</phrase>
<phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the current
fiber. It locks the spinlock protecting the internal state of a mutex
or condition_variable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Current fiber is set to waiting-state and gets suspended.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if fiber was
resumed before time-point <code><phrase role="identifier">timeout_time</phrase></code>
was reached, <code><phrase role="keyword">false</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is unlocked.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_wait_for_bridgehead">
<phrase id="algorithm_wait_for"/>
<link linkend="algorithm_wait_for">Member function
<code>wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">,</phrase>
<phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">spinlock</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">)</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the current
fiber. It locks the spinlock protecting the internal state of a mutex
or condition_variable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Current fiber is set to waiting-state and gets suspended.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if fiber was
resumed before time-duration <code><phrase role="identifier">timeout_duration</phrase></code>
has passed, <code><phrase role="keyword">false</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is unlocked.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_yield_bridgehead">
<phrase id="algorithm_yield"/>
<link linkend="algorithm_yield">Member function <code>yield</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends active fiber without waiting; that is, the current fiber is
immediately set to ready-state.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_get_main_id_bridgehead">
<phrase id="algorithm_get_main_id"/>
<link linkend="algorithm_get_main_id">Member
function <code>get_main_id</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_main_id</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A <code><phrase role="identifier">worker_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code> associated with the initial context
of the thread on which the scheduler is running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
While the initial context for a given thread is conceptually also a fiber,
it has no associated <code><phrase role="identifier">detail</phrase><phrase
role="special">::</phrase><phrase role="identifier">worker_fiber</phrase></code>
instance. Higher-level <emphasis role="bold">Boost.Fiber</emphasis> operations
treat a thread's initial context as equivalent to an explicitly-launched
fiber, but this method operates below that level of abstraction.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="algorithm_active"> <code>algorithm::active()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_get_main_fiber_bridgehead">
<phrase id="algorithm_get_main_fiber"/>
<link linkend="algorithm_get_main_fiber">Member
function <code>get_main_fiber</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="identifier">detail</phrase><phrase role="special">::</phrase><phrase role="identifier">notify</phrase><phrase role="special">::</phrase><phrase role="identifier">ptr_t</phrase> <phrase role="identifier">get_main_fiber</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A <code><phrase role="identifier">notify</phrase><phrase role="special">::</phrase><phrase
role="identifier">ptr_t</phrase></code> associated with the initial context
of the thread on which the scheduler is running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
While the initial context for a given thread is conceptually also a fiber,
it has no associated <code><phrase role="identifier">detail</phrase><phrase
role="special">::</phrase><phrase role="identifier">worker_fiber</phrase></code>
instance. Higher-level <emphasis role="bold">Boost.Fiber</emphasis> operations
treat a thread's initial context as equivalent to an explicitly-launched
fiber, but this method operates below that level of abstraction. The
<code><phrase role="identifier">notify</phrase><phrase role="special">::</phrase><phrase
role="identifier">ptr_t</phrase></code> is used in condition_variable
and mutex to signal threads initial context.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>See also:</term>
<listitem>
<para>
<link linkend="algorithm_active"> <code>algorithm::active()</code></link>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_round_robin_bridgehead">
<phrase id="class_round_robin"/>
<link linkend="class_round_robin">Class <code>round_robin</code></link>
</bridgehead>
</para>
<para>
This class implements <link linkend="class_algorithm"> <code>algorithm</code></link> and schedules fibers in round-robin
fashion.
</para>
<para>
<bridgehead renderas="sect4" id="class_round_robin_ws_bridgehead">
<phrase id="class_round_robin_ws"/>
<link linkend="class_round_robin_ws">Class
<code>round_robin_ws</code></link>
</bridgehead>
</para>
<para>
<code><phrase role="identifier">round_robin_ws</phrase></code> is intended
to be used for migrating fibers between threads (different schedulers). For
this purpose the class has two additional functions - <code><phrase role="identifier">steal_from</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">migrate_to</phrase><phrase
role="special">()</phrase></code>. This functionality can be used to implement
work-stealing/-sharing in a threadpool.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">round_robin_ws</phrase> <phrase role="identifier">rr</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">rr</phrase><phrase role="special">);</phrase>
<phrase role="comment">// steal a fiber from a scheduler `other_rr` running in another thread</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase> <phrase role="identifier">other_rr</phrase><phrase role="special">-&gt;</phrase><phrase role="identifier">steal_from</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="comment">// check if stealing was successful</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">f</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="comment">// migrate stolen fiber to scheduler running in this thread</phrase>
<phrase role="identifier">rr</phrase><phrase role="special">.</phrase><phrase role="identifier">migrate_to</phrase><phrase role="special">(</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="comment">// detach fiber</phrase>
<phrase role="identifier">f</phrase><phrase role="special">.</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
</programlisting>
</section>
<section id="fiber.stack">
<title><link linkend="fiber.stack">Stack allocation</link></title>
<para>
A <link linkend="class_fiber"> <code>fiber</code></link> uses internally a <emphasis>coroutine</emphasis> which manages
a set of registers and a stack. The memory used by the stack is allocated/deallocated
via a <link linkend="class_stack_allocator"> <code>stack_allocator</code></link>
which is required to model a <link
linkend="stack_allocator_concept"><emphasis>stack-allocator concept</emphasis></link>.
</para>
<anchor id="stack_allocator_concept"/>
<bridgehead renderas="sect3" id="fiber.stack.h0">
<phrase id="fiber.stack._link_linkend__stack_allocator_concept___emphasis_stack_allocator_concept__emphasis___link_"/><link
linkend="fiber.stack._link_linkend__stack_allocator_concept___emphasis_stack_allocator_concept__emphasis___link_"><link
linkend="stack_allocator_concept"><emphasis>stack-allocator concept</emphasis></link></link>
</bridgehead>
<para>
A <link linkend="class_stack_allocator"> <code>stack_allocator</code></link> must satisfy the <link linkend="stack_allocator_concept"><emphasis>stack-allocator
concept</emphasis></link> requirements shown in the following table, in which
<code><phrase role="identifier">a</phrase></code> is an object of a <link linkend="class_stack_allocator"> <code>stack_allocator</code></link> type,
<code><phrase role="identifier">sctx</phrase></code> is a <code><phrase role="identifier">stack_context</phrase></code>,
and <code><phrase role="identifier">size</phrase></code> is a <code><phrase
role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase></code>:
</para>
<informaltable frame="all">
<tgroup cols="3">
<thead>
<row>
<entry>
<para>
expression
</para>
</entry>
<entry>
<para>
return type
</para>
</entry>
<entry>
<para>
notes
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
role="identifier">allocate</phrase><phrase role="special">(</phrase>
<phrase role="identifier">sctx</phrase><phrase role="special">,</phrase>
<phrase role="identifier">size</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</entry>
<entry>
<para>
creates a stack of at least <code><phrase role="identifier">size</phrase></code>
bytes and stores both values in <code><phrase role="identifier">sctx</phrase></code>
</para>
</entry>
</row>
<row>
<entry>
<para>
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
role="identifier">deallocate</phrase><phrase role="special">(</phrase>
<phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</entry>
<entry>
<para>
deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code>
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<important>
<para>
The implementation of <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> might include logic to protect against
exceeding the context's available stack size rather than leaving it as undefined
behaviour.
</para>
</important>
<important>
<para>
Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
with a <code><phrase role="identifier">stack_context</phrase></code> not
previously passed to <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> results in undefined behaviour.
</para>
</important>
<note>
<para>
The memory for the stack is not required to be aligned; alignment takes place
inside <emphasis>coroutine</emphasis>.
</para>
</note>
<para>
<bridgehead renderas="sect4" id="class_stack_allocator_bridgehead">
<phrase id="class_stack_allocator"/>
<link linkend="class_stack_allocator">Class
<code>stack_allocator</code></link>
</bridgehead>
</para>
<para>
<ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink> provides
the class <emphasis>coroutine-allocator</emphasis> which models the <link linkend="stack_allocator_concept"><emphasis>stack-allocator
concept</emphasis></link>. It appends a guard page at the end of each stack
to protect against exceeding the stack. If the guard page is accessed (read
or write operation) a segmentation fault/access violation is generated by the
operating system.
</para>
<note>
<para>
The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
is <emphasis role="bold">not</emphasis> mapped to physical memory, only virtual
addresses are used.
</para>
</note>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">stack_allocator</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">stack_allocator</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="stack_allocator_is_stack_unbound_bridgehead">
<phrase id="stack_allocator_is_stack_unbound"/>
<link linkend="stack_allocator_is_stack_unbound">Static
member function <code>is_stack_unbound</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the environment
defines no limit for the size of a stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="stack_allocator_maximum_stacksize_bridgehead">
<phrase id="stack_allocator_maximum_stacksize"/>
<link linkend="stack_allocator_maximum_stacksize">Static
member function <code>maximum_stacksize</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the maximum size in bytes of stack defined by the environment.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="stack_allocator_default_stacksize_bridgehead">
<phrase id="stack_allocator_default_stacksize"/>
<link linkend="stack_allocator_default_stacksize">Static
member function <code>default_stacksize</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a default stack size, which may be platform specific. If <code><phrase
role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">true</phrase></code> then the present
implementation returns the maximum of <code><phrase role="number">64</phrase>
<phrase role="identifier">kB</phrase></code> and <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="stack_allocator_minimum_stacksize_bridgehead">
<phrase id="stack_allocator_minimum_stacksize"/>
<link linkend="stack_allocator_minimum_stacksize">Static
member function <code>minimum_stacksize</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the minimum size in bytes of stack required by the environment:
Win32 4kB, Win64 8kB, defined by rlimit on POSIX.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="stack_allocator_allocate_bridgehead">
<phrase id="stack_allocator_allocate"/>
<link linkend="stack_allocator_allocate">Member
function <code>allocate</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">size</phrase></code>
and <code><phrase role="special">!</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase
role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&lt;</phrase> <phrase
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
Bytes and stores a pointer to the stack and its actual size in <code><phrase
role="identifier">sctx</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Stores pointer to the start address of the new stack. Depending on the
architecture (stack grows downwards vs. upwards), the stored address
is the highest/lowest address of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="stack_allocator_deallocate_bridgehead">
<phrase id="stack_allocator_deallocate"/>
<link linkend="stack_allocator_deallocate">Member
function <code>deallocate</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">sctx</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&gt;</phrase> <phrase
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
<phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase>
<phrase role="special">&amp;&amp;</phrase> <phrase role="special">(</phrase>
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&lt;</phrase> <phrase role="identifier">size</phrase><phrase
role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deallocates the stack space.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">sctx</phrase></code> must have been set
by a previous call to <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_stack_context_bridgehead">
<phrase id="class_stack_context"/>
<link linkend="class_stack_context">Class <code>stack_context</code></link>
</bridgehead>
</para>
<para>
<ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink> provides
the class <link linkend="class_stack_context"> <code>stack_context</code></link> which will contain the stack pointer
and the size of the stack. In case of a <emphasis>segmented-stack</emphasis>,
<link linkend="class_stack_context"> <code>stack_context</code></link> contains some extra control structures.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
<phrase role="comment">// might contain additional control structures,</phrase>
<phrase role="comment">// for instance for segmented stacks</phrase>
<phrase role="special">}</phrase>
</programlisting>
<anchor id="stack_context_sp"/>
<bridgehead renderas="sect3" id="fiber.stack.h1">
<phrase id="fiber.stack.member_variable__code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/><link
linkend="fiber.stack.member_variable__code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_">Member
variable <code><phrase role="keyword">void</phrase> <phrase role="special">*</phrase>
<phrase role="identifier">sp</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Pointer to the beginning of the stack.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Whether the &quot;beginning&quot; of the stack is its lowest address
or its highest address is architecture-dependent.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="stack_context_size"/>
<bridgehead renderas="sect3" id="fiber.stack.h2">
<phrase id="fiber.stack.member_variable__code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"/><link
linkend="fiber.stack.member_variable__code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_">Member
variable <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">size_t</phrase> <phrase role="identifier">size</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Actual size of the stack, in bytes.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="fiber.stack.h3">
<phrase id="fiber.stack.segmented_stacks"/><link linkend="fiber.stack.segmented_stacks">Segmented
stacks</link>
</bridgehead>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> supports use of a <emphasis>segmented-stack</emphasis>,
whose size grows on demand. The fiber is created with a minimal stack size,
which will be increased as required.
</para>
<para>
Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
from version <emphasis role="bold">4.7</emphasis> onwards. In order to use
a <emphasis>segmented-stack</emphasis>, <emphasis role="bold">Boost.Fiber</emphasis>
must be built with <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis>
at b2/bjam command-line. Applications must be compiled with compiler-flags
<emphasis role="bold">-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS</emphasis>.
</para>
</section>
<section id="fiber.synchronization">
<title><link linkend="fiber.synchronization">Synchronization</link></title>
<section id="fiber.synchronization.mutex_types">
<title><link linkend="fiber.synchronization.mutex_types">Mutex Types</link></title>
<para>
<bridgehead renderas="sect4" id="class_mutex_bridgehead">
<phrase id="class_mutex"/>
<link linkend="class_mutex">Class <code>mutex</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">mutex</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<link linkend="class_mutex"> <code>mutex</code></link> provides an exclusive-ownership mutex. At most one fiber
can own the lock on a given instance of <link linkend="class_mutex"> <code>mutex</code></link> at any time. Multiple
concurrent calls to <code><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">try_lock</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> shall be permitted.
</para>
<para>
Any fiber blocked in <code><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code> is suspended in the scheduler until the
owning fiber releases the lock by calling <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code>.
</para>
<para>
<bridgehead renderas="sect4" id="class_timed_mutex_bridgehead">
<phrase id="class_timed_mutex"/>
<link linkend="class_timed_mutex">Class <code>timed_mutex</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">timed_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">timed_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">timed_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<link linkend="class_timed_mutex"> <code>timed_mutex</code></link> provides an exclusive-ownership mutex. At most
one fiber can own the lock on a given instance of <link linkend="class_timed_mutex"> <code>timed_mutex</code></link> at
any time. Multiple concurrent calls to <code><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">try_lock</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">try_lock_until</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">try_lock_for</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> shall be permitted.
</para>
<para>
<bridgehead renderas="sect4" id="class_recursive_mutex_bridgehead">
<phrase id="class_recursive_mutex"/>
<link linkend="class_recursive_mutex">Class
<code>recursive_mutex</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">recursive_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">recursive_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">recursive_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">recursive_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">recursive_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">recursive_mutex</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<link linkend="class_recursive_mutex"> <code>recursive_mutex</code></link> provides an exclusive-ownership recursive
mutex. At most one fiber can own the lock on a given instance of <link linkend="class_recursive_mutex"> <code>recursive_mutex</code></link> at
any time. Multiple concurrent calls to <code><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">try_lock</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> shall be permitted. A fiber that already
has exclusive ownership of a given <link linkend="class_recursive_mutex"> <code>recursive_mutex</code></link> instance
can call <code><phrase role="identifier">lock</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase></code>
to acquire an additional level of ownership of the mutex. <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> must be called once for each level of ownership
acquired by a single fiber before ownership can be acquired by another fiber.
</para>
<para>
<bridgehead renderas="sect4" id="class_recursive_timed_mutex_bridgehead">
<phrase id="class_recursive_timed_mutex"/>
<link linkend="class_recursive_timed_mutex">Class
<code>recursive_timed_mutex</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<link linkend="class_recursive_timed_mutex"> <code>recursive_timed_mutex</code></link> provides an exclusive-ownership
recursive mutex. At most one fiber can own the lock on a given instance of
<link linkend="class_recursive_timed_mutex"> <code>recursive_timed_mutex</code></link> at any time. Multiple concurrent
calls to <code><phrase role="identifier">lock</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">try_lock_for</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">try_lock_until</phrase><phrase role="special">()</phrase></code>
and <code><phrase role="identifier">unlock</phrase><phrase role="special">()</phrase></code>
shall be permitted. A fiber that already has exclusive ownership of a given
<link linkend="class_recursive_timed_mutex"> <code>recursive_timed_mutex</code></link> instance can call <code><phrase
role="identifier">lock</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">try_lock_for</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">try_lock_until</phrase><phrase role="special">()</phrase></code>
to acquire an additional level of ownership of the mutex. <code><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> must be called once for each level of ownership
acquired by a single fiber before ownership can be acquired by another fiber.
</para>
</section>
<section id="fiber.synchronization.conditions">
<title><link linkend="fiber.synchronization.conditions">Condition Variables</link></title>
<bridgehead renderas="sect4" id="fiber.synchronization.conditions.h0">
<phrase id="fiber.synchronization.conditions.synopsis"/><link linkend="fiber.synchronization.conditions.synopsis">Synopsis</link>
</bridgehead>
<programlisting><phrase role="keyword">enum</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">cv_status</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">no_timeout</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">condition_variable</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">condition_variable_any</phrase><phrase role="special">;</phrase>
</programlisting>
<para>
The class <code><phrase role="identifier">condition_variable</phrase></code>
provides a mechanism for one fiber to wait for notification on <code><phrase
role="identifier">condition_variable</phrase></code>. 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
<code><phrase role="identifier">wait</phrase></code> again to resume waiting.
In the simplest case, this condition is just a boolean variable:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">condition_variable</phrase> <phrase role="identifier">cond</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase> <phrase role="identifier">mtx</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">data_ready</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">process_data</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait_for_data_to_process</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase><phrase role="special">::</phrase><phrase role="identifier">scoped_lock</phrase> <phrase role="identifier">lk</phrase><phrase role="special">(</phrase> <phrase role="identifier">mtx</phrase><phrase role="special">);</phrase>
<phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">data_ready</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">cond</phrase><phrase role="special">.</phrase><phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">process_data</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
Notice that the <code><phrase role="identifier">lk</phrase></code> is passed
to <code><phrase role="identifier">wait</phrase></code>: <code><phrase role="identifier">wait</phrase></code>
will atomically add the fiber to the set of fibers waiting on the condition
variable, and unlock the mutex. When the fiber is awakened, the mutex will
be locked again before the call to <code><phrase role="identifier">wait</phrase></code>
returns. This allows other fibers to acquire the mutex in order to update
the shared data, and ensures that the data associated with the condition
is correctly synchronized.
</para>
<para>
In the meantime, another fiber sets the condition to <code><phrase role="keyword">true</phrase></code>,
and then calls either <code><phrase role="identifier">notify_one</phrase></code>
or <code><phrase role="identifier">notify_all</phrase></code> on the condition
variable to wake one waiting fiber or all the waiting fibers respectively.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">retrieve_data</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">prepare_data</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">prepare_data_for_processing</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">retrieve_data</phrase><phrase role="special">();</phrase>
<phrase role="identifier">prepare_data</phrase><phrase role="special">();</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lock_guard</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">(</phrase> <phrase role="identifier">mtx</phrase><phrase role="special">);</phrase>
<phrase role="identifier">data_ready</phrase> <phrase role="special">=</phrase> <phrase role="keyword">true</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">cond</phrase><phrase role="special">.</phrase><phrase role="identifier">notify_one</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
Note that the same mutex is locked before the shared data is updated, but
that the mutex does not have to be locked across the call to <code><phrase
role="identifier">notify_one</phrase></code>.
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides both <code><phrase
role="identifier">condition_variable</phrase></code> and <code><phrase role="identifier">condition_variable_any</phrase></code>
because <ulink url="boost:/libs/thread/index.html">Boost.Thread</ulink> provides
both. (<emphasis role="bold">Boost.Fiber</emphasis> also provides the name
<code><phrase role="identifier">condition</phrase></code>, which has been
deprecated in <ulink url="boost:/libs/thread/index.html">Boost.Thread</ulink>.)
However, <code><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">condition_variable</phrase></code> and <code><phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">condition_variable_any</phrase></code>
are the same class; like <code><phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">thread</phrase><phrase
role="special">::</phrase><phrase role="identifier">condition_variable_any</phrase></code>,
its wait() method will accept any form of lock. <code><phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">condition_variable_any</phrase></code>
has no need to further optimize as described for <code><phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">thread</phrase><phrase
role="special">::</phrase><phrase role="identifier">condition_variable</phrase></code>.
</para>
<para>
<bridgehead renderas="sect4" id="class_condition_variable_bridgehead">
<phrase id="class_condition_variable"/>
<link linkend="class_condition_variable">Class
<code>condition_variable</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">condition</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">enum</phrase> <phrase role="identifier">cv_status</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">no_timeout</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">condition_variable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">condition_variable</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">condition_variable</phrase><phrase role="special">();</phrase>
<phrase role="identifier">condition_variable</phrase><phrase role="special">(</phrase> <phrase role="identifier">condition_variable</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">condition_variable</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">condition_variable</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">notify_one</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">notify_all</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">predicate</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">condition_variable</phrase> <phrase role="identifier">condition_variable_any</phrase><phrase role="special">;</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.synchronization.conditions.h1">
<phrase id="fiber.synchronization.conditions.constructor"/><link linkend="fiber.synchronization.conditions.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">condition_variable</phrase><phrase role="special">()</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates the object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.conditions.h2">
<phrase id="fiber.synchronization.conditions.destructor"/><link linkend="fiber.synchronization.conditions.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">condition_variable</phrase><phrase role="special">()</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
All fibers waiting on <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> have been notified by a call to
<code><phrase role="identifier">notify_one</phrase></code> or <code><phrase
role="identifier">notify_all</phrase></code> (though the respective
calls to <code><phrase role="identifier">wait</phrase></code>, <code><phrase
role="identifier">wait_for</phrase></code> or <code><phrase role="identifier">wait_until</phrase></code>
need not have returned).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroys the object.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="condition_variable_notify_one_bridgehead">
<phrase id="condition_variable_notify_one"/>
<link linkend="condition_variable_notify_one">Member
function <code>notify_one</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">notify_one</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If any fibers are currently <link linkend="blocking"><emphasis>blocked</emphasis></link>
waiting on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
in a call to <code><phrase role="identifier">wait</phrase></code>,
<code><phrase role="identifier">wait_for</phrase></code> or <code><phrase
role="identifier">wait_until</phrase></code>, unblocks one of those
fibers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
It is arbitrary which waiting fiber is resumed.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="condition_variable_notify_all_bridgehead">
<phrase id="condition_variable_notify_all"/>
<link linkend="condition_variable_notify_all">Member
function <code>notify_all</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">notify_all</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If any fibers are currently <link linkend="blocking"><emphasis>blocked</emphasis></link>
waiting on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
in a call to <code><phrase role="identifier">wait</phrase></code>,
<code><phrase role="identifier">wait_for</phrase></code> or <code><phrase
role="identifier">wait_until</phrase></code>, unblocks all of those
fibers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This is why a waiting fiber must <emphasis>also</emphasis> check for
the desired program state using a mechanism external to the <code><phrase
role="identifier">condition_variable</phrase></code>, and retry the
wait until that state is reached. A fiber waiting on a <code><phrase
role="identifier">condition_variable</phrase></code> might well wake
up a number of times before the desired state is reached.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="condition_variable_wait_bridgehead">
<phrase id="condition_variable_wait"/>
<link linkend="condition_variable_wait">Templated
member function <code>wait</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber, and either no other fiber is currently waiting on <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>,
or the execution of the <code><phrase role="identifier">mutex</phrase><phrase
role="special">()</phrase></code> member function on the <code><phrase
role="identifier">lk</phrase></code> objects supplied in the calls
to <code><phrase role="identifier">wait</phrase></code> in all the
fibers currently waiting on <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> would return the same value as
<code><phrase role="identifier">lk</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">mutex</phrase><phrase role="special">()</phrase></code>
for this call to <code><phrase role="identifier">wait</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Atomically call <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> and blocks the current fiber. The
fiber will unblock when notified by a call to <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_one</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_all</phrase><phrase
role="special">()</phrase></code>, or spuriously. When the fiber is
unblocked (for whatever reason), the lock is reacquired by invoking
<code><phrase role="identifier">lk</phrase><phrase role="special">.</phrase><phrase
role="identifier">lock</phrase><phrase role="special">()</phrase></code>
before the call to <code><phrase role="identifier">wait</phrase></code>
returns. The lock is also reacquired by invoking <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code> if the function exits with an exception.
The member function accepting <code><phrase role="identifier">pred</phrase></code>
is shorthand for:
<programlisting><phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">pred</phrase><phrase role="special">())</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> if
an error occurs. <code><phrase role="identifier">fiber_interrupted</phrase></code>
if the wait was interrupted by a call to <link linkend="fiber_interrupt"> <code>fiber::interrupt()</code></link> on
the <link linkend="class_fiber"> <code>fiber</code></link> object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The Precondition is a bit dense. It merely states that all the fibers
calling <code><phrase role="identifier">wait</phrase></code> on <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
must wait on <code><phrase role="identifier">lk</phrase></code> objects
governing the <emphasis>same</emphasis> <code><phrase role="identifier">mutex</phrase></code>.
Three distinct objects are involved in any <code><phrase role="identifier">condition_variable</phrase><phrase
role="special">::</phrase><phrase role="identifier">wait</phrase><phrase
role="special">()</phrase></code> call: the <code><phrase role="identifier">condition_variable</phrase></code>
itself, the <code><phrase role="identifier">mutex</phrase></code> coordinating
access between fibers and a lock object (e.g. <code><phrase role="identifier">mutex</phrase><phrase
role="special">::</phrase><phrase role="identifier">scoped_lock</phrase></code>).
In some sense it would be nice if the <code><phrase role="identifier">condition_variable</phrase></code>'s
constructor could accept the related <code><phrase role="identifier">mutex</phrase></code>
object, enforcing agreement across all <code><phrase role="identifier">wait</phrase><phrase
role="special">()</phrase></code> calls; but the existing APIs prevent
that. Instead we must require the <code><phrase role="identifier">wait</phrase><phrase
role="special">()</phrase></code> call to accept a reference to the
local lock object. It is an error to reuse a given <code><phrase role="identifier">condition_variable</phrase></code>
instance with lock objects that reference <emphasis>different</emphasis>
underlying <code><phrase role="identifier">mutex</phrase></code> objects.
It would be like a road intersection with traffic lights disconnected
from one another: sooner or later a collision will result.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="condition_variable_wait_until_bridgehead">
<phrase id="condition_variable_wait_until"/>
<link linkend="condition_variable_wait_until">Templated
member function <code>wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber, and either no other fiber is currently waiting on <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>,
or the execution of the <code><phrase role="identifier">mutex</phrase><phrase
role="special">()</phrase></code> member function on the <code><phrase
role="identifier">lk</phrase></code> objects supplied in the calls
to <code><phrase role="identifier">wait</phrase></code>, <code><phrase
role="identifier">wait_for</phrase></code> or <code><phrase role="identifier">wait_until</phrase></code>
in all the fibers currently waiting on <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> would return the same value as
<code><phrase role="identifier">lk</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">mutex</phrase><phrase role="special">()</phrase></code>
for this call to <code><phrase role="identifier">wait</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Atomically call <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> and blocks the current fiber. The
fiber will unblock when notified by a call to <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_one</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_all</phrase><phrase
role="special">()</phrase></code>, when the time as reported by <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase></code>
would be equal to or later than the specified <code><phrase role="identifier">timeout_time</phrase></code>,
or spuriously. When the fiber is unblocked (for whatever reason), the
lock is reacquired by invoking <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code> before the call to <code><phrase
role="identifier">wait</phrase></code> returns. The lock is also reacquired
by invoking <code><phrase role="identifier">lk</phrase><phrase role="special">.</phrase><phrase
role="identifier">lock</phrase><phrase role="special">()</phrase></code>
if the function exits with an exception. The member function accepting
<code><phrase role="identifier">pred</phrase></code> is shorthand for:
<programlisting><phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">pred</phrase><phrase role="special">()</phrase> <phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase role="identifier">timeout</phrase> <phrase role="special">==</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">pred</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">return</phrase> <phrase role="keyword">true</phrase><phrase role="special">;</phrase>
</programlisting>
That is, even if <code><phrase role="identifier">wait_until</phrase><phrase
role="special">()</phrase></code> times out, it can still return <code><phrase
role="keyword">true</phrase></code> if <code><phrase role="identifier">pred</phrase><phrase
role="special">()</phrase></code> returns <code><phrase role="keyword">true</phrase></code>
at that time.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> if
an error occurs. <code><phrase role="identifier">fiber_interrupted</phrase></code>
if the wait was interrupted by a call to <link linkend="fiber_interrupt"> <code>fiber::interrupt()</code></link> on
the <link linkend="class_fiber"> <code>fiber</code></link> object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The overload without <code><phrase role="identifier">pred</phrase></code>
returns <code><phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_timeout</phrase></code> if awakened by <code><phrase
role="identifier">notify_one</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">notify_all</phrase><phrase role="special">()</phrase></code>,
or <code><phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase
role="identifier">timeout</phrase></code> if awakened because <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase></code>
is past <code><phrase role="identifier">timeout_time</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The overload accepting <code><phrase role="identifier">pred</phrase></code>
returns <code><phrase role="keyword">false</phrase></code> if the call
is returning because the time specified by <code><phrase role="identifier">timeout_time</phrase></code>
was reached and the predicate returns <code><phrase role="keyword">false</phrase></code>,
<code><phrase role="keyword">true</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
See <emphasis role="bold">Note</emphasis> for <code><phrase role="identifier">wait</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="condition_variable_wait_for_bridgehead">
<phrase id="condition_variable_wait_for"/>
<link linkend="condition_variable_wait_for">Templated
member function <code>wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber, and either no other fiber is currently waiting on <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>,
or the execution of the <code><phrase role="identifier">mutex</phrase><phrase
role="special">()</phrase></code> member function on the <code><phrase
role="identifier">lk</phrase></code> objects supplied in the calls
to <code><phrase role="identifier">wait</phrase></code>, <code><phrase
role="identifier">wait_for</phrase></code> or <code><phrase role="identifier">wait_until</phrase></code>
in all the fibers currently waiting on <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> would return the same value as
<code><phrase role="identifier">lk</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">mutex</phrase><phrase role="special">()</phrase></code>
for this call to <code><phrase role="identifier">wait</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Atomically call <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> and blocks the current fiber. The
fiber will unblock when notified by a call to <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_one</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_all</phrase><phrase
role="special">()</phrase></code>, when a time interval equal to or
greater than the specified <code><phrase role="identifier">timeout_duration</phrase></code>
has elapsed, or spuriously. When the fiber is unblocked (for whatever
reason), the lock is reacquired by invoking <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code> before the call to <code><phrase
role="identifier">wait</phrase></code> returns. The lock is also reacquired
by invoking <code><phrase role="identifier">lk</phrase><phrase role="special">.</phrase><phrase
role="identifier">lock</phrase><phrase role="special">()</phrase></code>
if the function exits with an exception. The member function accepting
<code><phrase role="identifier">pred</phrase></code> is shorthand for:
<programlisting><phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="special">!</phrase> <phrase role="identifier">pred</phrase><phrase role="special">()</phrase> <phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase role="identifier">timeout</phrase> <phrase role="special">==</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">pred</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">return</phrase> <phrase role="keyword">true</phrase><phrase role="special">;</phrase>
</programlisting>
That is, even if <code><phrase role="identifier">wait_for</phrase><phrase
role="special">()</phrase></code> times out, it can still return <code><phrase
role="keyword">true</phrase></code> if <code><phrase role="identifier">pred</phrase><phrase
role="special">()</phrase></code> returns <code><phrase role="keyword">true</phrase></code>
at that time.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> if
an error occurs. <code><phrase role="identifier">fiber_interrupted</phrase></code>
if the wait was interrupted by a call to <link linkend="fiber_interrupt"> <code>fiber::interrupt()</code></link> on
the <link linkend="class_fiber"> <code>fiber</code></link> object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The overload without <code><phrase role="identifier">pred</phrase></code>
returns <code><phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_timeout</phrase></code> if awakened by <code><phrase
role="identifier">notify_one</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">notify_all</phrase><phrase role="special">()</phrase></code>,
or <code><phrase role="identifier">cv_status</phrase><phrase role="special">::</phrase><phrase
role="identifier">timeout</phrase></code> if awakened because at least
<code><phrase role="identifier">timeout_duration</phrase></code> has
elapsed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The overload accepting <code><phrase role="identifier">pred</phrase></code>
returns <code><phrase role="keyword">false</phrase></code> if the call
is returning because at least <code><phrase role="identifier">timeout_duration</phrase></code>
has elapsed and the predicate returns <code><phrase role="keyword">false</phrase></code>,
<code><phrase role="keyword">true</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
See <emphasis role="bold">Note</emphasis> for <code><phrase role="identifier">wait</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.barriers">
<title><link linkend="fiber.synchronization.barriers">Barriers</link></title>
<para>
A barrier is a concept also known as a <emphasis>rendezvous</emphasis>, it
is a synchronization point between multiple contexts of execution (fibers).
The barrier is configured for a particular number of fibers (<code><phrase
role="identifier">n</phrase></code>), and as fibers reach the barrier they
must wait until all <code><phrase role="identifier">n</phrase></code> fibers
have arrived. Once the <code><phrase role="identifier">n</phrase></code>-th
fiber has reached the barrier, all the waiting fibers can proceed, and the
barrier is reset.
</para>
<para>
<bridgehead renderas="sect4" id="class_barrier_bridgehead">
<phrase id="class_barrier"/>
<link linkend="class_barrier">Class <code>barrier</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">barrier</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">barrier</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">barrier</phrase><phrase role="special">(</phrase> <phrase role="keyword">unsigned</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">initial</phrase><phrase role="special">);</phrase>
<phrase role="identifier">barrier</phrase><phrase role="special">(</phrase> <phrase role="identifier">barrier</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">barrier</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">barrier</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait</phrase><phrase role="special">();</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
Instances of <link linkend="class_barrier"> <code>barrier</code></link> are not copyable or movable.
</para>
<bridgehead renderas="sect4" id="fiber.synchronization.barriers.h0">
<phrase id="fiber.synchronization.barriers.constructor"/><link linkend="fiber.synchronization.barriers.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">barrier</phrase><phrase role="special">(</phrase> <phrase role="keyword">unsigned</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">initial</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Construct a barrier for <code><phrase role="identifier">initial</phrase></code>
fibers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">invalid_argument</phrase></code> if <code><phrase
role="identifier">initial</phrase></code> is zero
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="barrier_wait_bridgehead">
<phrase id="barrier_wait"/>
<link linkend="barrier_wait">Member function <code>wait</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">wait</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Block until <code><phrase role="identifier">initial</phrase></code>
fibers have called <code><phrase role="identifier">wait</phrase></code>
on <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
When the <code><phrase role="identifier">initial</phrase></code>-th
fiber calls <code><phrase role="identifier">wait</phrase></code>, all
waiting fibers are unblocked, and the barrier is reset.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> for exactly one fiber
from each batch of waiting fibers, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
interruption point
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.queues">
<title><link linkend="fiber.synchronization.queues">Queues</link></title>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides a bounded and a unbounded
queue suitable to synchonize fibers via message passing.
</para>
<programlisting><phrase role="keyword">typedef</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">unbounded_queue</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">queue_t</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">send</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">for</phrase> <phrase role="special">(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;</phrase> <phrase role="number">5</phrase><phrase role="special">;</phrase> <phrase role="special">++</phrase><phrase role="identifier">i</phrase><phrase role="special">)</phrase>
<phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">close</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">recv</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">queue_op_status</phrase><phrase role="special">::</phrase><phrase role="identifier">success</phrase> <phrase role="special">==</phrase> <phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">pop</phrase><phrase role="special">(</phrase><phrase role="identifier">i</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase>
<phrase role="special">{</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">cout</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="string">&quot;received &quot;</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> <phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">queue_t</phrase> <phrase role="identifier">queue</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase> <phrase role="identifier">send</phrase><phrase role="special">,</phrase> <phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase> <phrase role="identifier">recv</phrase><phrase role="special">,</phrase> <phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase role="identifier">join</phrase><phrase role="special">();</phrase>
<phrase role="identifier">f2</phrase><phrase role="special">.</phrase><phrase role="identifier">join</phrase><phrase role="special">();</phrase>
</programlisting>
<anchor id="class_queue_op_status"/>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h0">
<phrase id="fiber.synchronization.queues.enumeration__code__phrase_role__identifier__queue_op_status__phrase___code_"/><link
linkend="fiber.synchronization.queues.enumeration__code__phrase_role__identifier__queue_op_status__phrase___code_">Enumeration
<code><phrase role="identifier">queue_op_status</phrase></code></link>
</bridgehead>
<para>
Queue operations return the state of the queue.
</para>
<programlisting><phrase role="keyword">enum</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">queue_op_status</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">success</phrase><phrase role="special">,</phrase>
<phrase role="identifier">empty</phrase><phrase role="special">,</phrase>
<phrase role="identifier">full</phrase><phrase role="special">,</phrase>
<phrase role="identifier">closed</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h1">
<phrase id="fiber.synchronization.queues._code__phrase_role__identifier__success__phrase___code_"/><link
linkend="fiber.synchronization.queues._code__phrase_role__identifier__success__phrase___code_"><code><phrase
role="identifier">success</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Operation was successful.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h2">
<phrase id="fiber.synchronization.queues._code__phrase_role__identifier__empty__phrase___code_"/><link
linkend="fiber.synchronization.queues._code__phrase_role__identifier__empty__phrase___code_"><code><phrase
role="identifier">empty</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Queue is empty, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h3">
<phrase id="fiber.synchronization.queues._code__phrase_role__identifier__full__phrase___code_"/><link
linkend="fiber.synchronization.queues._code__phrase_role__identifier__full__phrase___code_"><code><phrase
role="identifier">full</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Queue is full, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h4">
<phrase id="fiber.synchronization.queues._code__phrase_role__identifier__closed__phrase___code_"/><link
linkend="fiber.synchronization.queues._code__phrase_role__identifier__closed__phrase___code_"><code><phrase
role="identifier">closed</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Queue is closed, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h5">
<phrase id="fiber.synchronization.queues._code__phrase_role__identifier__timeout__phrase___code_"/><link
linkend="fiber.synchronization.queues._code__phrase_role__identifier__timeout__phrase___code_"><code><phrase
role="identifier">timeout</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The operation did not become ready before specified timeout elapsed.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_unbounded_queue_bridgehead">
<phrase id="class_unbounded_queue"/>
<link linkend="class_unbounded_queue">Template
<code>unbounded_queue&lt;&gt;</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">unbounded_queue</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">unbounded_queue</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">T</phrase> <phrase role="identifier">value_type</phrase><phrase role="special">;</phrase>
<phrase role="identifier">unbounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">unbounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">unbounded_queue</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">unbounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_closed</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">close</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_empty</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_is_closed_bridgehead">
<phrase id="unbounded_queue_is_closed"/>
<link linkend="unbounded_queue_is_closed">Member
function <code>is_closed</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_closed</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if queue has been
closed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The queue is not closed by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_close_bridgehead">
<phrase id="unbounded_queue_close"/>
<link linkend="unbounded_queue_close">Member
function <code>close</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">close</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deactivates the queue. No values can be put after calling <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">close</phrase><phrase role="special">()</phrase></code>.
Fibers blocked in <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_until</phrase><phrase
role="special">()</phrase></code> will return <code><phrase role="identifier">closed</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">close</phrase><phrase role="special">()</phrase></code>
is like closing a pipe. It informs waiting consumers that no more values
will arrive.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_is_empty_bridgehead">
<phrase id="unbounded_queue_is_empty"/>
<link linkend="unbounded_queue_is_empty">Member
function <code>is_empty</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_empty</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the queue
currently contains no data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This condition is transient. An <code><phrase role="identifier">is_empty</phrase><phrase
role="special">()</phrase></code> queue can become non-empty.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_push_bridgehead">
<phrase id="unbounded_queue_push"/>
<link linkend="unbounded_queue_push">Member
function <code>push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Enqueues the value in the queue and wakes up a fiber blocked on <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop_wait_for</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop_wait_until</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_pop_bridgehead">
<phrase id="unbounded_queue_pop"/>
<link linkend="unbounded_queue_pop">Member
function <code>pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If the queue <code><phrase role="identifier">is_empty</phrase><phrase
role="special">()</phrase></code>, the fiber gets suspended until at
least one new item is <code><phrase role="identifier">push</phrase><phrase
role="special">()</phrase></code>ed (return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value) or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_pop_wait_for_bridgehead">
<phrase id="unbounded_queue_pop_wait_for"/>
<link linkend="unbounded_queue_pop_wait_for">Member
function <code>pop_wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts <code><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">duration</phrase></code> and internally computes
a <code><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> as <code><phrase role="special">(</phrase><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase> <phrase
role="special">+</phrase> <phrase role="identifier">timeout_duration</phrase><phrase
role="special">)</phrase></code>. If <code><phrase role="special">(!</phrase>
<phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_empty</phrase><phrase role="special">())</phrase></code>,
immediately dequeues a value from the queue. Otherwise the fiber gets
suspended until at least one new item is <code><phrase role="identifier">push</phrase><phrase
role="special">()</phrase></code>ed (return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value), or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the computed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_pop_wait_until_bridgehead">
<phrase id="unbounded_queue_pop_wait_until"/>
<link linkend="unbounded_queue_pop_wait_until">Member
function <code>pop_wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts a <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">time_point</phrase></code>.
If <code><phrase role="special">(!</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_empty</phrase><phrase
role="special">())</phrase></code>, immediately dequeues a value from
the queue. Otherwise the fiber gets suspended until at least one new
item is <code><phrase role="identifier">push</phrase><phrase role="special">()</phrase></code>ed
(return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value), or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the passed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_queue_try_pop_bridgehead">
<phrase id="unbounded_queue_try_pop"/>
<link linkend="unbounded_queue_try_pop">Member
function <code>try_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_empty</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">empty</phrase></code>. If
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_closed</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">closed</phrase></code>. Otherwise
it returns <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains the
dequeued value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_bounded_queue_bridgehead">
<phrase id="class_bounded_queue"/>
<link linkend="class_bounded_queue">Template
<code>bounded_queue&lt;&gt;</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">bounded_queue</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">bounded_queue</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">T</phrase> <phrase role="identifier">value_type</phrase><phrase role="special">;</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">bounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">bounded_queue</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">bounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">wm</phrase><phrase role="special">);</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">hwm</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lwm</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_closed</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">close</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_empty</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_full</phrase><phrase role="special">();</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.synchronization.queues.h6">
<phrase id="fiber.synchronization.queues.constructor"/><link linkend="fiber.synchronization.queues.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">wm</phrase><phrase role="special">);</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">hwm</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lwm</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">hwm</phrase> <phrase role="special">&gt;=</phrase>
<phrase role="identifier">lwm</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs an object of class <code><phrase role="identifier">bounded_queue</phrase></code>.
The constructor with two arguments constructs an object of class <code><phrase
role="identifier">bounded_queue</phrase></code> with a high-watermark
of <code><phrase role="identifier">hwm</phrase></code> and a low-watermark
of <code><phrase role="identifier">lwm</phrase></code> items. The constructor
with one argument effectively sets both <code><phrase role="identifier">hwm</phrase></code>
and <code><phrase role="identifier">lwm</phrase></code> to the same
value <code><phrase role="identifier">wm</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">invalid_argument</phrase></code> if
<code><phrase role="identifier">lwm</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">hwm</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Notes:</term>
<listitem>
<para>
Once the number of values in the queue reaches <code><phrase role="identifier">hwm</phrase></code>,
any call to <code><phrase role="identifier">push</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">push_wait_for</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">push_wait_until</phrase><phrase
role="special">()</phrase></code> will block until the number of values
in the queue has dropped below <code><phrase role="identifier">lwm</phrase></code>.
That is, if <code><phrase role="identifier">lwm</phrase> <phrase role="special">&lt;</phrase>
<phrase role="identifier">hwm</phrase></code>, the queue can be in
a state in which <code><phrase role="identifier">push</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="identifier">push_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="identifier">push_wait_until</phrase><phrase
role="special">()</phrase></code> calls will block (<code><phrase role="identifier">is_full</phrase><phrase
role="special">()</phrase></code> returns <code><phrase role="keyword">true</phrase></code>)
even though the number of values in the queue is less than <code><phrase
role="identifier">hwm</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_is_closed_bridgehead">
<phrase id="bounded_queue_is_closed"/>
<link linkend="bounded_queue_is_closed">Member
function <code>is_closed</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_closed</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase></code> if queue has been
closed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The queue is not closed by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_close_bridgehead">
<phrase id="bounded_queue_close"/>
<link linkend="bounded_queue_close">Member
function <code>close</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">close</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deactivates the queue. No values can be put after calling <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">close</phrase><phrase role="special">()</phrase></code>.
Fibers blocked in <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_until</phrase><phrase
role="special">()</phrase></code> will return <code><phrase role="identifier">closed</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">close</phrase><phrase role="special">()</phrase></code>
is like closing a pipe. It informs waiting consumers that no more values
will arrive.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_is_empty_bridgehead">
<phrase id="bounded_queue_is_empty"/>
<link linkend="bounded_queue_is_empty">Member
function <code>is_empty</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_empty</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the queue
currently contains no data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This condition is transient. An <code><phrase role="identifier">is_empty</phrase><phrase
role="special">()</phrase></code> queue can become non-empty.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_is_full_bridgehead">
<phrase id="bounded_queue_is_full"/>
<link linkend="bounded_queue_is_full">Member
function <code>is_full</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_full</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the queue
cannot accept more data at present. This happens when the number of
values in the queue reaches <code><phrase role="identifier">wm</phrase></code>
or <code><phrase role="identifier">hwm</phrase></code>. Once the queue
becomes full, however, it continues refusing new values until the number
of values drops below <code><phrase role="identifier">lwm</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This condition is transient.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_push_bridgehead">
<phrase id="bounded_queue_push"/>
<link linkend="bounded_queue_push">Member function
<code>push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_closed</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">closed</phrase></code>. If
<code><phrase role="special">(!</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_full</phrase><phrase
role="special">())</phrase></code>, enqueues the value in the queue,
wakes up a fiber blocked on <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_until</phrase><phrase
role="special">()</phrase></code> and returns <code><phrase role="identifier">success</phrase></code>.
Otherwise the fiber gets suspended until the number of values in the
queue drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
or the queue is <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_push_wait_for_bridgehead">
<phrase id="bounded_queue_push_wait_for"/>
<link linkend="bounded_queue_push_wait_for">Member
function <code>push_wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts <code><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">duration</phrase></code> and internally computes
a <code><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> as <code><phrase role="special">(</phrase><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase> <phrase
role="special">+</phrase> <phrase role="identifier">timeout_duration</phrase><phrase
role="special">)</phrase></code>. If <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_closed</phrase><phrase
role="special">()</phrase></code>, returns <code><phrase role="identifier">closed</phrase></code>.
If <code><phrase role="special">(!</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_full</phrase><phrase
role="special">())</phrase></code>, enqueues the value in the queue,
wakes up a fiber blocked on <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop</phrase><phrase
role="special">()</phrase></code> <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_until</phrase><phrase
role="special">()</phrase></code> and returns <code><phrase role="identifier">success</phrase></code>.
Otherwise the fiber gets suspended until the number of values in the
queue drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
the queue is <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the computed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_push_wait_until_bridgehead">
<phrase id="bounded_queue_push_wait_until"/>
<link linkend="bounded_queue_push_wait_until">Member
function <code>push_wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">push_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts a <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">time_point</phrase></code>.
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_closed</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">closed</phrase></code>. If
<code><phrase role="special">(!</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_full</phrase><phrase
role="special">())</phrase></code>, enqueues the value in the queue,
wakes up a fiber blocked on <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop</phrase><phrase
role="special">()</phrase></code>, <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_for</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">pop_wait_until</phrase><phrase
role="special">()</phrase></code> and returns <code><phrase role="identifier">success</phrase></code>.
Otherwise the fiber gets suspended until the number of values in the
queue drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
the queue is <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the passed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_try_push_bridgehead">
<phrase id="bounded_queue_try_push"/>
<link linkend="bounded_queue_try_push">Member
function <code>try_push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_push</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_full</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">full</phrase></code>. If <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_closed</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">closed</phrase></code>. Otherwise
enqueues the value in the queue, wakes up a fiber blocked on <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop_wait_for</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">pop_wait_until</phrase><phrase role="special">()</phrase></code>
and returns <code><phrase role="identifier">success</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_pop_bridgehead">
<phrase id="bounded_queue_pop"/>
<link linkend="bounded_queue_pop">Member function
<code>pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If the queue <code><phrase role="identifier">is_empty</phrase><phrase
role="special">()</phrase></code>, the fiber gets suspended until at
least one new item is <code><phrase role="identifier">push</phrase><phrase
role="special">()</phrase></code>ed (return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value) or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>).
Once the number of items remaining in the queue drops below <code><phrase
role="identifier">lwm</phrase></code>, any fibers blocked on <code><phrase
role="identifier">push</phrase><phrase role="special">()</phrase></code>,
<code><phrase role="identifier">push_wait_for</phrase><phrase role="special">()</phrase></code>
or <code><phrase role="identifier">push_wait_until</phrase><phrase
role="special">()</phrase></code> may resume.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_pop_wait_for_bridgehead">
<phrase id="bounded_queue_pop_wait_for"/>
<link linkend="bounded_queue_pop_wait_for">Member
function <code>pop_wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts <code><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">duration</phrase></code> and internally computes
a <code><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> as <code><phrase role="special">(</phrase><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase> <phrase
role="special">+</phrase> <phrase role="identifier">timeout_duration</phrase><phrase
role="special">)</phrase></code>. If <code><phrase role="special">(!</phrase>
<phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_empty</phrase><phrase role="special">())</phrase></code>,
immediately dequeues a value from the queue. Otherwise the fiber gets
suspended until at least one new item is <code><phrase role="identifier">push</phrase><phrase
role="special">()</phrase></code>ed (return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value), or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the computed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_pop_wait_until_bridgehead">
<phrase id="bounded_queue_pop_wait_until"/>
<link linkend="bounded_queue_pop_wait_until">Member
function <code>pop_wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">pop_wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">,</phrase>
<phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Accepts a <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">time_point</phrase></code>.
If <code><phrase role="special">(!</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">is_empty</phrase><phrase
role="special">())</phrase></code>, immediately dequeues a value from
the queue. Otherwise the fiber gets suspended until at least one new
item is <code><phrase role="identifier">push</phrase><phrase role="special">()</phrase></code>ed
(return value <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains dequeued
value), or the queue gets <code><phrase role="identifier">close</phrase><phrase
role="special">()</phrase></code>d (return value <code><phrase role="identifier">closed</phrase></code>),
or the time as reported by <code><phrase role="identifier">clock_type</phrase><phrase
role="special">::</phrase><phrase role="identifier">now</phrase><phrase
role="special">()</phrase></code> reaches the passed <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase></code> (return value <code><phrase
role="identifier">timeout</phrase></code>).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_queue_try_pop_bridgehead">
<phrase id="bounded_queue_try_pop"/>
<link linkend="bounded_queue_try_pop">Member
function <code>try_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">queue_op_status</phrase> <phrase role="identifier">try_pop</phrase><phrase role="special">(</phrase> <phrase role="identifier">value_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_empty</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">empty</phrase></code>. If
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">is_closed</phrase><phrase role="special">()</phrase></code>,
returns <code><phrase role="identifier">closed</phrase></code>. Otherwise
it returns <code><phrase role="identifier">success</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains the
dequeued value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.futures">
<title><link linkend="fiber.synchronization.futures">Futures</link></title>
<bridgehead renderas="sect4" id="fiber.synchronization.futures.h0">
<phrase id="fiber.synchronization.futures.overview"/><link linkend="fiber.synchronization.futures.overview">Overview</link>
</bridgehead>
<para>
The futures library provides a means of handling synchronous future values,
whether those values are generated by another fiber, or on a single fiber
in response to external stimuli, or on-demand.
</para>
<para>
This is done through the provision of four class templates: <link linkend="class_future"> <code>future&lt;&gt;</code></link> and
<link linkend="class_shared_future"> <code>shared_future&lt;&gt;</code></link> which are used to retrieve the asynchronous
results, and <link linkend="class_promise"> <code>promise&lt;&gt;</code></link> and <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link> which
are used to generate the asynchronous results.
</para>
<para>
An instance of <link linkend="class_future"> <code>future&lt;&gt;</code></link> holds the one and only reference
to a result. Ownership can be transferred between instances using the move
constructor or move-assignment operator, but at most one instance holds a
reference to a given asynchronous result. When the result is ready, it is
returned from <link linkend="future_get"> <code>future::get()</code></link> by rvalue-reference to allow the result
to be moved or copied as appropriate for the type.
</para>
<para>
On the other hand, many instances of <link linkend="class_shared_future"> <code>shared_future&lt;&gt;</code></link> may
reference the same result. Instances can be freely copied and assigned, and
<link linkend="shared_future_get"> <code>shared_future::get()</code></link>
returns a non <code><phrase role="keyword">const</phrase></code>
reference so that multiple calls to <link linkend="shared_future_get"> <code>shared_future::get()</code></link>
are
safe. You can move an instance of <link linkend="class_future"> <code>future&lt;&gt;</code></link> into an instance
of <link linkend="class_shared_future"> <code>shared_future&lt;&gt;</code></link>, thus transferring ownership
of the associated asynchronous result, but not vice-versa.
</para>
<para>
<code><phrase role="identifier">async</phrase><phrase role="special">()</phrase></code>
is a simple way of running asynchronous tasks. A call to <code><phrase role="identifier">async</phrase><phrase
role="special">()</phrase></code> returns a <link linkend="class_future"> <code>future&lt;&gt;</code></link> that
will deliver the result of the task.
</para>
<bridgehead renderas="sect4" id="fiber.synchronization.futures.h1">
<phrase id="fiber.synchronization.futures.creating_asynchronous_values"/><link
linkend="fiber.synchronization.futures.creating_asynchronous_values">Creating
asynchronous values</link>
</bridgehead>
<para>
You can set the value in a future with either a <link linkend="class_promise"> <code>promise&lt;&gt;</code></link> or
a <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link>. A <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link> is
a callable object with <code><phrase role="keyword">void</phrase></code>
return that wraps a function or callable object returning the specified type.
When the <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link> is invoked, it invokes the
contained function in turn, and populates a future with the contained function's
return value. This is an answer to the perennial question: &quot;How do I
return a value from a fiber?&quot; Package the function you wish to run as
a <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link> and pass the packaged task to the
fiber constructor. The future retrieved from the packaged task can then be
used to obtain the return value. If the function throws an exception, that
is stored in the future in place of the return value.
</para>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">calculate_the_answer_to_life_the_universe_and_everything</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">return</phrase> <phrase role="number">42</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">packaged_task</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">()&gt;</phrase> <phrase role="identifier">pt</phrase><phrase role="special">(</phrase><phrase role="identifier">calculate_the_answer_to_life_the_universe_and_everything</phrase><phrase role="special">);</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">fi</phrase><phrase role="special">=</phrase><phrase role="identifier">pt</phrase><phrase role="special">.</phrase><phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">pt</phrase><phrase role="special">)).</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase> <phrase role="comment">// launch task on a fiber</phrase>
<phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">wait</phrase><phrase role="special">();</phrase> <phrase role="comment">// wait for it to finish</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">is_ready</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_value</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(!</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_exception</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">()==</phrase><phrase role="number">42</phrase><phrase role="special">);</phrase>
</programlisting>
<para>
A <link linkend="class_promise"> <code>promise&lt;&gt;</code></link> is a bit more low level: it just provides explicit
functions to store a value or an exception in the associated future. A promise
can therefore be used where the value might come from more than one possible
source, or where a single operation may produce multiple values.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">promise</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">pi</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">fi</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fi</phrase><phrase role="special">=</phrase><phrase role="identifier">pi</phrase><phrase role="special">.</phrase><phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="identifier">pi</phrase><phrase role="special">.</phrase><phrase role="identifier">set_value</phrase><phrase role="special">(</phrase><phrase role="number">42</phrase><phrase role="special">);</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">is_ready</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_value</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(!</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_exception</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">()==</phrase><phrase role="number">42</phrase><phrase role="special">);</phrase>
</programlisting>
<section id="fiber.synchronization.futures.future">
<title><link linkend="fiber.synchronization.futures.future">Future</link></title>
<para>
A future provides a mechanism to access the result of an asynchronous operation.
</para>
<anchor id="class_future_status"/>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h0">
<phrase id="fiber.synchronization.futures.future.enumeration__code__phrase_role__identifier__future_status__phrase___code_"/><link
linkend="fiber.synchronization.futures.future.enumeration__code__phrase_role__identifier__future_status__phrase___code_">Enumeration
<code><phrase role="identifier">future_status</phrase></code></link>
</bridgehead>
<para>
Timed wait-operations ( <link linkend="future_wait_for"> <code>future::wait_for()</code></link> and <link linkend="future_wait_until"> <code>future::wait_until()</code></link>)
return the state of the future.
</para>
<programlisting><phrase role="keyword">enum</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">future_status</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">ready</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase><phrase role="special">,</phrase>
<phrase role="identifier">deferred</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h1">
<phrase id="fiber.synchronization.futures.future._code__phrase_role__identifier__ready__phrase___code_"/><link
linkend="fiber.synchronization.futures.future._code__phrase_role__identifier__ready__phrase___code_"><code><phrase
role="identifier">ready</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The shared state is ready.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h2">
<phrase id="fiber.synchronization.futures.future._code__phrase_role__identifier__timeout__phrase___code_"/><link
linkend="fiber.synchronization.futures.future._code__phrase_role__identifier__timeout__phrase___code_"><code><phrase
role="identifier">timeout</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The shared state did not become ready before timeout has passed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h3">
<phrase id="fiber.synchronization.futures.future._code__phrase_role__identifier__deferred__phrase___code_"/><link
linkend="fiber.synchronization.futures.future._code__phrase_role__identifier__deferred__phrase___code_"><code><phrase
role="identifier">deferred</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The function is deferred, e.g. result will be computed only when
explictly requested.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_future_bridgehead">
<phrase id="class_future"/>
<link linkend="class_future">Template <code>future&lt;&gt;</code></link>
</bridgehead>
</para>
<para>
A <link linkend="class_future"> <code>future&lt;&gt;</code></link> contains a shared state which is not shared
with any other future.
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">future</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">future</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">future</phrase><phrase role="special">();</phrase>
<phrase role="identifier">future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">future</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">share</phrase><phrase role="special">();</phrase>
<phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h4">
<phrase id="fiber.synchronization.futures.future.default_constructor"/><link
linkend="fiber.synchronization.futures.future.default_constructor">Default
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a future with no shared state. After construction is <code><phrase
role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">vaild</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h5">
<phrase id="fiber.synchronization.futures.future.move_constructor"/><link
linkend="fiber.synchronization.futures.future.move_constructor">Move constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">future</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs a future with the shared state of other. After construction
is <code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h6">
<phrase id="fiber.synchronization.futures.future.destructor"/><link linkend="fiber.synchronization.futures.future.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destructs the future; ownership is abandoned.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_operator_assign_bridgehead">
<phrase id="future_operator_assign"/>
<link linkend="future_operator_assign">Member
function <code>operator=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Moves the shared state of other to <code><phrase role="keyword">this</phrase></code>.
After construction is <code><phrase role="keyword">false</phrase>
<phrase role="special">==</phrase> <phrase role="identifier">other</phrase><phrase
role="special">.</phrase><phrase role="identifier">valid</phrase><phrase
role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_swap_bridgehead">
<phrase id="future_swap"/>
<link linkend="future_swap">Member function <code>swap</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the shared state between other and <code><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_operator safe_bool_bridgehead">
<phrase id="future_operator safe_bool"/>
<link linkend="future_operator
safe_bool">Member function <code>operator safe_bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if future
is valid.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_operator_not_bridgehead">
<phrase id="future_operator_not"/>
<link linkend="future_operator_not">Member
function <code>operator!</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">false</phrase></code> if future
is valid.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_valid_bridgehead">
<phrase id="future_valid"/>
<link linkend="future_valid">Member function <code>valid</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if future
contains a shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_share_bridgehead">
<phrase id="future_share"/>
<link linkend="future_share">Member function <code>share</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">shared_future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">share</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Move the state to a <link linkend="class_shared_future"> <code>shared_future&lt;&gt;</code></link>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_get_bridgehead">
<phrase id="future_get"/>
<link linkend="future_get">Member function <code>get</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns the result.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_wait_bridgehead">
<phrase id="future_wait"/>
<link linkend="future_wait">Member function <code>wait</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_wait_for_bridgehead">
<phrase id="future_wait_for"/>
<link linkend="future_wait_for">Templated member
function <code>wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_duration</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="future_wait_until_bridgehead">
<phrase id="future_wait_until"/>
<link linkend="future_wait_until">Member function
<code>wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_time</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="class_shared_future_bridgehead">
<phrase id="class_shared_future"/>
<link linkend="class_shared_future">Template
<code>shared_future&lt;&gt;</code></link>
</bridgehead>
</para>
<para>
A <link linkend="class_shared_future"> <code>shared_future&lt;&gt;</code></link> contains a shared state which
might be shared with other futures.
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">shared_future</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">shared_future</phrase><phrase role="special">();</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h7">
<phrase id="fiber.synchronization.futures.future.default_constructor0"/><link
linkend="fiber.synchronization.futures.future.default_constructor0">Default
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">shared_future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a future with no shared state. After construction is <code><phrase
role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">vaild</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h8">
<phrase id="fiber.synchronization.futures.future.move_constructor0"/><link
linkend="fiber.synchronization.futures.future.move_constructor0">Move constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs a future with the shared state of other. After construction
is <code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">valid</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h9">
<phrase id="fiber.synchronization.futures.future.copy_constructor"/><link
linkend="fiber.synchronization.futures.future.copy_constructor">Copy constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">shared_future</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="identifier">cosnt</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs a future with the shared state of other. After construction
is <code><phrase role="keyword">true</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">other</phrase><phrase role="special">.</phrase><phrase
role="identifier">valid</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.future.h10">
<phrase id="fiber.synchronization.futures.future.destructor0"/><link linkend="fiber.synchronization.futures.future.destructor0">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">shared_future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destructs the future; ownership is abandoned if not shared.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_operator_assign_bridgehead">
<phrase id="shared_future_operator_assign"/>
<link linkend="shared_future_operator_assign">Member
function <code>operator=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Transfers the ownership of shared state according to:
<programlisting><phrase role="identifier">shared_future</phrase> <phrase role="identifier">tmp</phrase><phrase role="special">(</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">tmp</phrase><phrase role="special">);</phrase>
<phrase role="keyword">return</phrase> <phrase role="special">*</phrase> <phrase role="keyword">this</phrase><phrase role="special">;</phrase>
</programlisting>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_swap_bridgehead">
<phrase id="shared_future_swap"/>
<link linkend="shared_future_swap">Member
function <code>swap</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">shared_future</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the shared state between other and <code><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_operator safe_bool_bridgehead">
<phrase id="shared_future_operator safe_bool"/>
<link linkend="shared_future_operator
safe_bool">Member function <code>operator safe_bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if future
is valid.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_operator_not_bridgehead">
<phrase id="shared_future_operator_not"/>
<link linkend="shared_future_operator_not">Member
function <code>operator!</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">false</phrase></code> if future
is valid.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_valid_bridgehead">
<phrase id="shared_future_valid"/>
<link linkend="shared_future_valid">Member
function <code>valid</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if future
contains a shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_get_bridgehead">
<phrase id="shared_future_get"/>
<link linkend="shared_future_get">Member function
<code>get</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns the result.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_wait_bridgehead">
<phrase id="shared_future_wait"/>
<link linkend="shared_future_wait">Member
function <code>wait</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_wait_for_bridgehead">
<phrase id="shared_future_wait_for"/>
<link linkend="shared_future_wait_for">Templated
member function <code>wait_for</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_duration</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="shared_future_wait_until_bridgehead">
<phrase id="shared_future_wait_until"/>
<link linkend="shared_future_wait_until">Member
function <code>wait_until</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_time</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.futures.promise">
<title><anchor id="class_promise"/><link linkend="fiber.synchronization.futures.promise">Template
<code><phrase role="identifier">promise</phrase><phrase role="special">&lt;&gt;</phrase></code></link></title>
<para>
A <link linkend="class_promise"> <code>promise&lt;&gt;</code></link> provides a mechanism to store a value that
can later be accessed asynchronously by a <link linkend="class_future"> <code>future&lt;&gt;</code></link> object.
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">promise</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">promise</phrase><phrase role="special">();</phrase>
<phrase role="identifier">promise</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">promise</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">promise</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_value</phrase><phrase role="special">(</phrase> <phrase role="identifier">R</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">value</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_value</phrase><phrase role="special">(</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">value</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">exception_ptr</phrase> <phrase role="identifier">p</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.promise.h0">
<phrase id="fiber.synchronization.futures.promise.default_constructor"/><link
linkend="fiber.synchronization.futures.promise.default_constructor">Default
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">promise</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a promise with an empty shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.promise.h1">
<phrase id="fiber.synchronization.futures.promise.constructor"/><link linkend="fiber.synchronization.futures.promise.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a promise with an empty shared state by using <code><phrase
role="identifier">alloc</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.promise.h2">
<phrase id="fiber.synchronization.futures.promise.move_constructor"/><link
linkend="fiber.synchronization.futures.promise.move_constructor">Move constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a promise by moving the shared state from <code><phrase role="identifier">other</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase></code> contains no
valid shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.promise.h3">
<phrase id="fiber.synchronization.futures.promise.destructor"/><link linkend="fiber.synchronization.futures.promise.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">promise</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroys <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
and abandons the shared state if shared state is ready; otherwise
stores <code><phrase role="identifier">future_error</phrase></code>
with error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">broken_promise</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_operator_assign_bridgehead">
<phrase id="promise_operator_assign"/>
<link linkend="promise_operator_assign">Member
function <code>operator=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">promise</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Transfers the ownership of shared state to <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase></code> contains no
valid shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_swap_bridgehead">
<phrase id="promise_swap"/>
<link linkend="promise_swap">Member function <code>swap</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the shared state between other and <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_operator safe_bool_bridgehead">
<phrase id="promise_operator safe_bool"/>
<link linkend="promise_operator
safe_bool">Member function <code>operator safe_bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
contains a non-empty shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_operator_not_bridgehead">
<phrase id="promise_operator_not"/>
<link linkend="promise_operator_not">Member
function <code>operator!</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
contains an empty shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_get_future_bridgehead">
<phrase id="promise_get_future"/>
<link linkend="promise_get_future">Member
function <code>get_future</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A <link linkend="class_future"> <code>future&lt;&gt;</code></link> with the same shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">future_already_retrieved</phrase></code> or <code><phrase
role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_set_value_bridgehead">
<phrase id="promise_set_value"/>
<link linkend="promise_set_value">Member function
<code>set_value</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">set_value</phrase><phrase role="special">(</phrase> <phrase role="identifier">R</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">value</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">set_value</phrase><phrase role="special">(</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">value</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Store the result in the shared state and marks the state as ready.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">future_already_satisfied</phrase></code> or <code><phrase
role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="promise_set_exception_bridgehead">
<phrase id="promise_set_exception"/>
<link linkend="promise_set_exception">Member
function <code>set_exception</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">set_exception</phrase><phrase role="special">(</phrase> <phrase role="identifier">exception_ptr</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Store an exception pointer in the shared state and marks the state
as ready.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">future_already_satisfied</phrase></code> or <code><phrase
role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.futures.packaged_task">
<title><anchor id="class_packaged_task"/><link linkend="fiber.synchronization.futures.packaged_task">Template
<code><phrase role="identifier">packaged_task</phrase><phrase role="special">&lt;&gt;</phrase></code></link></title>
<para>
A <link linkend="class_packaged_task"> <code>packaged_task&lt;&gt;</code></link> wraps a callable target that
returns a value so that the return value can be computed asynchronously.
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase><phrase role="special">()</phrase> <phrase role="special">&gt;</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">packaged_task</phrase><phrase role="special">();</phrase>
<phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">();</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.packaged_task.h0">
<phrase id="fiber.synchronization.futures.packaged_task.default_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_"/><link
linkend="fiber.synchronization.futures.packaged_task.default_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_">Default
constructor <code><phrase role="identifier">packaged_task</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">packaged_task</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs an object of class <code><phrase role="identifier">packaged_task</phrase></code>
with no shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.packaged_task.h1">
<phrase id="fiber.synchronization.futures.packaged_task.templated_constructor__code__phrase_role__keyword__template__phrase__phrase_role__special___lt__gt___phrase___phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_"/><link
linkend="fiber.synchronization.futures.packaged_task.templated_constructor__code__phrase_role__keyword__template__phrase__phrase_role__special___lt__gt___phrase___phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_">Templated
constructor <code><phrase role="keyword">template</phrase><phrase role="special">&lt;&gt;</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs an object of class <code><phrase role="identifier">packaged_task</phrase></code>
with a shared state and stores the callable target <code><phrase
role="identifier">fn</phrase></code> internally.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The signature of <code><phrase role="identifier">Fn</phrase></code>
should have a return type convertible to <code><phrase role="identifier">R</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.packaged_task.h2">
<phrase id="fiber.synchronization.futures.packaged_task.move_constructor"/><link
linkend="fiber.synchronization.futures.packaged_task.move_constructor">Move
constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a packaged_task by moving the shared state from <code><phrase
role="identifier">other</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase></code> contains no
valid shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect5" id="fiber.synchronization.futures.packaged_task.h3">
<phrase id="fiber.synchronization.futures.packaged_task.destructor"/><link
linkend="fiber.synchronization.futures.packaged_task.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">packaged_task</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroys <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
and abandons the shared state if shared state is ready; otherwise
stores <code><phrase role="identifier">future_error</phrase></code>
with error condition <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">broken_promise</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_operator_assign_bridgehead">
<phrase id="packaged_task_operator_assign"/>
<link linkend="packaged_task_operator_assign">Member
function <code>operator=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Transfers the ownership of shared state to <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="identifier">other</phrase></code> contains no
valid shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_swap_bridgehead">
<phrase id="packaged_task_swap"/>
<link linkend="packaged_task_swap">Member
function <code>swap</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">swap</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Swaps the shared state between other and <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_operator safe_bool_bridgehead">
<phrase id="packaged_task_operator safe_bool"/>
<link linkend="packaged_task_operator
safe_bool">Member function <code>operator safe_bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
contains a non-empty shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_operator_not_bridgehead">
<phrase id="packaged_task_operator_not"/>
<link linkend="packaged_task_operator_not">Member
function <code>operator!</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
contains an empty shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_valid_bridgehead">
<phrase id="packaged_task_valid"/>
<link linkend="packaged_task_valid">Member
function <code>valid</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
contains a shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_get_future_bridgehead">
<phrase id="packaged_task_get_future"/>
<link linkend="packaged_task_get_future">Member
function <code>get_future</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A <link linkend="class_future"> <code>future&lt;&gt;</code></link> with the same shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">future_already_retrieved</phrase></code> or <code><phrase
role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_operator_apply_bridgehead">
<phrase id="packaged_task_operator_apply"/>
<link linkend="packaged_task_operator_apply">Member
function <code>operator()</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Invokes the stored callable target. Any exception thrown by the callable
target <code><phrase role="identifier">fn</phrase></code> is stored
in the shared state. Otherwise, the value returned by <code><phrase
role="identifier">fn</phrase></code> is stored in the shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="packaged_task_reset_bridgehead">
<phrase id="packaged_task_reset"/>
<link linkend="packaged_task_reset">Member
function <code>reset</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Resets the shared state and abondons the result of previous executions.
A new shared state is constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
</section>
</section>
<section id="fiber.fls">
<title><link linkend="fiber.fls">Fiber local storage</link></title>
<bridgehead renderas="sect3" id="fiber.fls.h0">
<phrase id="fiber.fls.synopsis"/><link linkend="fiber.fls.synopsis">Synopsis</link>
</bridgehead>
<para>
Fiber local storage allows a separate instance of a given data item for each
fiber.
</para>
<bridgehead renderas="sect3" id="fiber.fls.h1">
<phrase id="fiber.fls.cleanup_at_fiber_exit"/><link linkend="fiber.fls.cleanup_at_fiber_exit">Cleanup
at fiber exit</link>
</bridgehead>
<para>
When a fiber exits, the objects associated with each <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> instance
are destroyed. By default, the object pointed to by a pointer <code><phrase
role="identifier">p</phrase></code> is destroyed by invoking <code><phrase
role="keyword">delete</phrase> <phrase role="identifier">p</phrase></code>,
but this can be overridden for a specific instance of <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> by
providing a cleanup routine <code><phrase role="identifier">func</phrase></code>
to the constructor. In this case, the object is destroyed by invoking <code><phrase
role="identifier">func</phrase><phrase role="special">(</phrase><phrase role="identifier">p</phrase><phrase
role="special">)</phrase></code>. The cleanup functions are called in an unspecified
order.
</para>
<para>
<bridgehead renderas="sect4" id="class_fiber_specific_ptr_bridgehead">
<phrase id="class_fiber_specific_ptr"/>
<link linkend="class_fiber_specific_ptr">Class
<code>fiber_specific_ptr</code></link>
</bridgehead>
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">fss</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber_specific_ptr</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">T</phrase> <phrase role="identifier">element_type</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">();</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase><phrase role="special">(*</phrase><phrase role="identifier">fn</phrase><phrase role="special">)(</phrase><phrase role="identifier">T</phrase><phrase role="special">*)</phrase> <phrase role="special">);</phrase>
<phrase role="special">~</phrase><phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">();</phrase>
<phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_specific_ptr</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber_specific_ptr</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber_specific_ptr</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">T</phrase> <phrase role="special">*</phrase> <phrase role="identifier">get</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">T</phrase> <phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">-&gt;()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">T</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">*()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">T</phrase> <phrase role="special">*</phrase> <phrase role="identifier">release</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">(</phrase> <phrase role="identifier">T</phrase> <phrase role="special">*</phrase> <phrase role="identifier">t</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.fls.h2">
<phrase id="fiber.fls.constructor"/><link linkend="fiber.fls.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">();</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">(</phrase> <phrase role="keyword">void</phrase><phrase role="special">(*</phrase><phrase role="identifier">fn</phrase><phrase role="special">)(</phrase><phrase role="identifier">T</phrase><phrase role="special">*)</phrase> <phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Requires:</term>
<listitem>
<para>
<code><phrase role="keyword">delete</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> is well-formed; fn(this-&gt;get())
does not throw
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Construct a <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> object for storing
a pointer to an object of type <code><phrase role="identifier">T</phrase></code>
specific to each fiber. When <code><phrase role="identifier">reset</phrase><phrase
role="special">()</phrase></code> is called, or the fiber exits, <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> calls
<code><phrase role="identifier">fn</phrase><phrase role="special">(</phrase><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">())</phrase></code>.
If the no-arguments constructor is used, the default <code><phrase role="keyword">delete</phrase></code>-based
cleanup function will be used to destroy the fiber-local objects.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_resource_error</phrase></code>
if an error occurs.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect3" id="fiber.fls.h3">
<phrase id="fiber.fls.destructor"/><link linkend="fiber.fls.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber_specific_ptr</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Requires:</term>
<listitem>
<para>
All the fiber specific instances associated to this <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link>
(except
maybe the one associated to this fiber) must be null.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Calls <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">reset</phrase><phrase role="special">()</phrase></code>
to clean up the associated value for the current fiber, and destroys
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Remarks:</term>
<listitem>
<para>
The requirement is due to the fact that in order to delete all these
instances, the implementation should be forced to maintain a list of
all the fibers having an associated specific ptr, which is against the
goal of fiber specific data. In general, a <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> should
outlive the fibers that use it.
</para>
</listitem>
</varlistentry>
</variablelist>
<note>
<para>
Care needs to be taken to ensure that any fibers still running after an instance
of <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> has been destroyed do not call
any member functions on that instance.
</para>
</note>
<para>
<bridgehead renderas="sect4" id="fiber_specific_ptr_get_bridgehead">
<phrase id="fiber_specific_ptr_get"/>
<link linkend="fiber_specific_ptr_get">Member
function <code>get</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">T</phrase><phrase role="special">*</phrase> <phrase role="identifier">get</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The pointer associated with the current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<note>
<para>
The initial value associated with an instance of <link linkend="class_fiber_specific_ptr"> <code>fiber_specific_ptr</code></link> is
<code><phrase role="identifier">NULL</phrase></code> for each fiber.
</para>
</note>
<para>
<bridgehead renderas="sect4" id="fiber_specific_ptr_operator_arrow_bridgehead">
<phrase id="fiber_specific_ptr_operator_arrow"/>
<link linkend="fiber_specific_ptr_operator_arrow">Member
function <code>operator-&gt;</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">T</phrase><phrase role="special">*</phrase> <phrase role="keyword">operator</phrase><phrase role="special">-&gt;()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_specific_ptr_operator_star_bridgehead">
<phrase id="fiber_specific_ptr_operator_star"/>
<link linkend="fiber_specific_ptr_operator_star">Member
function <code>operator*</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">T</phrase><phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">*()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Requires:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase></code> is not <code><phrase role="identifier">NULL</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="special">*(</phrase><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">())</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_specific_ptr_release_bridgehead">
<phrase id="fiber_specific_ptr_release"/>
<link linkend="fiber_specific_ptr_release">Member
function <code>release</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">T</phrase><phrase role="special">*</phrase> <phrase role="identifier">release</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Return <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()</phrase></code>
and store <code><phrase role="identifier">NULL</phrase></code> as the
pointer associated with the current fiber without invoking the cleanup
function.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()==</phrase><phrase
role="number">0</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_specific_ptr_reset_bridgehead">
<phrase id="fiber_specific_ptr_reset"/>
<link linkend="fiber_specific_ptr_reset">Member
function <code>reset</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">(</phrase><phrase role="identifier">T</phrase><phrase role="special">*</phrase> <phrase role="identifier">new_value</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()!=</phrase><phrase
role="identifier">new_value</phrase></code> and <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> is non-<code><phrase role="identifier">NULL</phrase></code>,
invoke <code><phrase role="keyword">delete</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="identifier">fn</phrase><phrase
role="special">(</phrase><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">())</phrase></code> as appropriate. Store <code><phrase
role="identifier">new_value</phrase></code> as the pointer associated
with the current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()==</phrase><phrase
role="identifier">new_value</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_resource_error</phrase></code>
if an error occurs.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.asio">
<title><link linkend="fiber.asio">Asynchronous network I/O (boost.asio)</link></title>
<para>
In the past, code using asio's <emphasis>asynchronous operations</emphasis>
was scattered by callbacks. <ulink url="boost:/libs/asio/index.html">Boost.Asio</ulink>
provides with its new <emphasis>asynchronous result</emphasis> feature a new
way to simplify the code and make it easier to read. <emphasis>boost::asio::yield_context</emphasis>
internally uses <ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink>:
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">echo</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">ip</phrase><phrase role="special">::</phrase><phrase role="identifier">tcp</phrase><phrase role="special">::</phrase><phrase role="identifier">socket</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">yield_context</phrase> <phrase role="identifier">yield</phrase><phrase role="special">){</phrase>
<phrase role="keyword">char</phrase> <phrase role="identifier">data</phrase><phrase role="special">[</phrase><phrase role="number">128</phrase><phrase role="special">];</phrase>
<phrase role="comment">// read asynchronous data from socket</phrase>
<phrase role="comment">// execution context will be suspended until</phrase>
<phrase role="comment">// some bytes are read from socket</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="identifier">socket</phrase><phrase role="special">.</phrase><phrase role="identifier">async_read_some</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="comment">// write some bytes asynchronously</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_write</phrase><phrase role="special">(</phrase><phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">,</phrase><phrase role="identifier">n</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
Unfortunately <ulink url="boost:/libs/coroutine/index.html">Boost.Coroutine</ulink>
(<emphasis>boost::asio::yield_context</emphasis>) does not provide primitives
to synchronize different coroutines (execution contexts).
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides an integration of <code><phrase
role="identifier">fibers</phrase></code> into <ulink url="boost:/libs/asio/index.html">Boost.Asio</ulink>
so that <emphasis>asynchronous operations</emphasis> from <ulink url="boost:/libs/asio/index.html">Boost.Asio</ulink>
can be used together with fibers, synchronized by primitives provided by <emphasis
role="bold">Boost.Fiber</emphasis>.
</para>
<para>
The example section contains a complete publish-subscribe application demonstrating
the use of fibers with asio's <emphasis>asynchronous operations</emphasis>.
<emphasis>boost::fibers::asio::yield_context</emphasis> abstracts the fiber
in asio's context.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">subscriber</phrase><phrase role="special">::</phrase><phrase role="identifier">run</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">yield_fiber</phrase> <phrase role="identifier">yield</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">system</phrase><phrase role="special">::</phrase><phrase role="identifier">error_code</phrase> <phrase role="identifier">ec</phrase><phrase role="special">;</phrase>
<phrase role="comment">// read first message == channel name</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">channel</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_read</phrase><phrase role="special">(</phrase>
<phrase role="identifier">socket_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase> <phrase role="identifier">channel</phrase><phrase role="special">),</phrase>
<phrase role="identifier">yield</phrase><phrase role="special">[</phrase><phrase role="identifier">ec</phrase><phrase role="special">]);</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">ec</phrase><phrase role="special">)</phrase> <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">&quot;no channel from subscriber&quot;</phrase><phrase role="special">);</phrase>
<phrase role="comment">// register new channel</phrase>
<phrase role="identifier">reg_</phrase><phrase role="special">.</phrase><phrase role="identifier">subscribe</phrase><phrase role="special">(</phrase> <phrase role="identifier">channel</phrase><phrase role="special">,</phrase> <phrase role="identifier">shared_from_this</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase><phrase role="special">::</phrase><phrase role="identifier">scoped_lock</phrase> <phrase role="identifier">lk</phrase><phrase role="special">(</phrase> <phrase role="identifier">mtx_</phrase><phrase role="special">);</phrase>
<phrase role="comment">// wait for published messages</phrase>
<phrase role="comment">// fiber gets suspended and will be woken up if a</phrase>
<phrase role="comment">// new message has to be published to subscriber</phrase>
<phrase role="identifier">cond_</phrase><phrase role="special">.</phrase><phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="comment">// '&lt;fini&gt;' terminates subscriber</phrase>
<phrase role="comment">// data_ is a private member of subscriber and</phrase>
<phrase role="comment">// gets filled by the publisher</phrase>
<phrase role="comment">// notification of available data via condition_var cond_</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="string">&quot;&lt;fini&gt;&quot;</phrase> <phrase role="special">==</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">(</phrase> <phrase role="identifier">data_</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="keyword">break</phrase><phrase role="special">;</phrase>
<phrase role="comment">// write message asynchronously to subscriber</phrase>
<phrase role="comment">// fiber gets suspended until message was written</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_write</phrase><phrase role="special">(</phrase>
<phrase role="identifier">socket_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase> <phrase role="identifier">data_</phrase><phrase role="special">,</phrase> <phrase role="identifier">max_length</phrase><phrase role="special">),</phrase>
<phrase role="identifier">yield</phrase><phrase role="special">[</phrase><phrase role="identifier">ec</phrase><phrase role="special">]);</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">ec</phrase><phrase role="special">)</phrase> <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">&quot;publishing message failed&quot;</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
</programlisting>
<bridgehead renderas="sect3" id="fiber.asio.h0">
<phrase id="fiber.asio.c10k_problem"/><link linkend="fiber.asio.c10k_problem">C10K
problem</link>
</bridgehead>
<para>
The C10K-website <footnote id="fiber.asio.f0">
<para>
<ulink url="http://www.kegel.com/c10k.html">'The C10K problem', Dan Kegel</ulink>
</para>
</footnote> from Dan Kegel describes the problem of handling ten thousand clients
simultaneously and which strategies are possible.
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> and <ulink url="boost:/libs/asio/index.html">Boost.Asio</ulink>
support the strategy 'serve many clients with each server thread, and use asynchronous
I/O' without scattering the logic across many callbacks (as was asio's previous
strategy) and overloading the operating system with too many threads. (Beyond
a certain number of threads, the overhead of the kernel scheduler starts to
swamp the available cores.)
</para>
<para>
Because <emphasis role="bold">Boost.Fiber</emphasis> contains synchronization
primitives, it is easy to synchronize different fibers and use asynchronous
network I/O at the same time.
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides the same classes and
interfaces as <ulink url="boost:/libs/thread/index.html">Boost.Thread</ulink>.
Therefore developers are able to use patterns familiar from multi-threaded
programming. For instance the strategy 'serve one client with one thread' could
be transformed into 'serve one client with one fiber'.
</para>
</section>
<section id="fiber.performance">
<title><link linkend="fiber.performance">Performance</link></title>
<para>
Performance measurements were taken using <code><phrase role="identifier">boost</phrase><phrase
role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase
role="special">::</phrase><phrase role="identifier">highresolution_clock</phrase></code>,
with overhead corrections. The code was compiled using the build options, 'variant
= release cxxflags = -DBOOST_DISABLE_ASSERTS optimization = speed'.
</para>
<para>
The numbers in the table are the number of ns, based upon an average computed
over 1000 iterations.
</para>
<table frame="all" id="fiber.performance.perfomance_of_coroutine_switch">
<title>Perfomance of coroutine switch</title>
<tgroup cols="4">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
qthread
</para>
</entry>
<entry>
<para>
tbb
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
37114 ns
</para>
</entry>
<entry>
<para>
577 ns
</para>
</entry>
<entry>
<para>
309 ns
</para>
</entry>
<entry>
<para>
37981 ns
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="fiber.acknowledgements">
<title><link linkend="fiber.acknowledgements">Acknowledgments</link></title>
<para>
I'd like to thank Yuriy Krasnoschek and especially Nat Goodspeed.
</para>
</section>
</library>