2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-17 13:42:21 +00:00
Files
fiber/doc/fibers.xml
Oliver Kowalke 5d18cd5a4e add interruption point after fiber_manager::run()
- functions fiber_manager::join()/fiber_manager::yield()/fiber_manager:.wait()/fiber_manager_wait_until()
  check for interrption of the current fiber
2015-06-21 10:53:37 +02:00

7756 lines
466 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: 2015/06/21 08:51:14 $"
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 <emphasis>execution_context</emphasis> from <ulink url="boost:/libs/context/index.html">Boost.Context</ulink>;
the classes in this library manage, schedule and, when needed, synchronize
those execution contexts. 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/context/index.html">Boost.Context</ulink>.
Boost version 1.58.0 or greater is required.
</para>
<para>
[info This library is C++14-only!]
</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">struct</phrase> <phrase role="identifier">sched_algorithm</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">sched_algorithm_with_properties</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">sched_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">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">PROPS</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">properties</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">std</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>std::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">std</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>
The spawned <link linkend="class_fiber"> <code>fiber</code></link> is enqueued in the list of ready-to-run fibers
at construction.
</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>
A exception thrown by the function or callable object passed to the <link linkend="class_fiber"> <code>fiber</code></link>
constructor
calls <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">terminate</phrase><phrase role="special">()</phrase></code>.
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="mutex_lock"> <code>mutex::lock()</code></link> ( <link linkend="class_recursive_mutex"> <code>recursive_mutex</code></link>, <link linkend="class_recursive_timed_mutex"> <code>recursive_timed_mutex</code></link>,
<link linkend="class_timed_mutex"> <code>timed_mutex</code></link>)
</simpara>
</listitem>
<listitem>
<simpara>
<link linkend="mutex_try_lock"> <code>mutex::try_lock()</code></link> ( <link linkend="class_recursive_mutex"> <code>recursive_mutex</code></link>,
<link linkend="class_recursive_timed_mutex"> <code>recursive_timed_mutex</code></link>, <link linkend="class_timed_mutex"> <code>timed_mutex</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_yield"> <code>this_fiber::yield()</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">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">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</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="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</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">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</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">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">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">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="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">PROPS</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">properties</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">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</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="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="identifier">salloc</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">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</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 <emphasis>execution_context</emphasis>.
</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>
<para>
&lt; TODO &gt; <anchor id="fiber_properties"/>
</para>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.fiber.h5">
<phrase id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__props__phrase___phrase_role__special___gt___phrase___phrase_role__identifier__props__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__properties__phrase__phrase_role__special______phrase___code_"/><link
linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__template__phrase__phrase_role__special___lt___phrase___phrase_role__keyword__typename__phrase___phrase_role__identifier__props__phrase___phrase_role__special___gt___phrase___phrase_role__identifier__props__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__properties__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">PROPS</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">PROPS</phrase>
<phrase role="special">&amp;</phrase> <phrase role="identifier">properties</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">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">PROPS</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">properties</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>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fiber_operator bool_bridgehead">
<phrase id="fiber_operator bool"/>
<link linkend="fiber_operator bool">Member
function <code>operator bool</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">explicit</phrase> <phrase role="keyword">operator</phrase> <phrase role="keyword">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">sched_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_sched_algorithm"> <code>sched_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_sched_algorithm"> <code>sched_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 create 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">sched_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.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.fiber_mgmt.id">
<title><anchor id="class_id"/><link linkend="fiber.fiber_mgmt.id">Class fiber::id</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">id</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">id</phrase><phrase role="special">()</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="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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">&lt;(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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">&gt;(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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">&lt;=(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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">&gt;=(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</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">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">friend</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase>
<phrase role="keyword">operator</phrase><phrase role="special">&lt;&lt;(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<bridgehead renderas="sect4" id="fiber.fiber_mgmt.id.h0">
<phrase id="fiber.fiber_mgmt.id.constructor"/><link linkend="fiber.fiber_mgmt.id.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">id</phrase><phrase role="special">()</phrase> <phrase role="keyword">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Represents an instance of <emphasis>not-a-fiber</emphasis>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="id_operator_equal_bridgehead">
<phrase id="id_operator_equal"/>
<link linkend="id_operator_equal">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="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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>
and <code><phrase role="identifier">other</phrase></code> represent
the same fiber, or both represent <emphasis>not-a-fiber</emphasis>,
<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="id_operator_not_equal_bridgehead">
<phrase id="id_operator_not_equal"/>
<link linkend="id_operator_not_equal">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="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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>
`! (other == * this)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="id_operator_less_bridgehead">
<phrase id="id_operator_less"/>
<link linkend="id_operator_less">Member function
<code>operator&lt;</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&lt;(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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> <phrase
role="special">!=</phrase> <phrase role="identifier">other</phrase></code>
is true and the implementation-defined total order of <code><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code> values places <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> before <code><phrase role="identifier">other</phrase></code>,
false otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="id_operator_greater_bridgehead">
<phrase id="id_operator_greater"/>
<link linkend="id_operator_greater">Member
function <code>operator&gt;</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&gt;(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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="identifier">other</phrase> <phrase role="special">&lt;</phrase>
<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="id_operator_less_equal_bridgehead">
<phrase id="id_operator_less_equal"/>
<link linkend="id_operator_less_equal">Member
function <code>operator&lt;=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&lt;=(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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="special">!</phrase> <phrase role="special">(</phrase><phrase
role="identifier">other</phrase> <phrase role="special">&lt;</phrase>
<phrase role="special">*</phrase> <phrase role="keyword">this</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="id_operator_greater_equal_bridgehead">
<phrase id="id_operator_greater_equal"/>
<link linkend="id_operator_greater_equal">Member
function <code>operator&gt;=</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&gt;=(</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</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="special">!</phrase> <phrase role="special">(*</phrase>
<phrase role="keyword">this</phrase> <phrase role="special">&lt;</phrase>
<phrase role="identifier">other</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.id.h1">
<phrase id="fiber.fiber_mgmt.id.operator_lt__lt_"/><link linkend="fiber.fiber_mgmt.id.operator_lt__lt_">operator&lt;&lt;</link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase>
<phrase role="keyword">operator</phrase><phrase role="special">&lt;&lt;(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">basic_ostream</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">charT</phrase><phrase role="special">,</phrase> <phrase role="identifier">traitsT</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">os</phrase><phrase role="special">,</phrase> <phrase role="identifier">id</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Efects:</term>
<listitem>
<para>
Writes the representation of <code><phrase role="identifier">other</phrase></code>
to stream <code><phrase role="identifier">os</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="identifier">os</phrase></code>
</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">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">PROPS</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">properties</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">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sleep_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">std</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 std::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>
&lt; TODO &gt;
</para>
<para>
<bridgehead renderas="sect4" id="this_fiber_properties_bridgehead">
<phrase id="this_fiber_properties"/>
<link linkend="this_fiber_properties">Non-member
function <code>this_fiber::properties()</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">typename</phrase> <phrase role="identifier">PROPS</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">PROPS</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">properties</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
</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>
<phrase role="keyword">void</phrase> <phrase role="identifier">interruption_point</phrase><phrase role="special">();</phrase>
</programlisting>
<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 id="fiber.fiber_mgmt.winfibers">
<title><link linkend="fiber.fiber_mgmt.winfibers">Using WinFiber-API</link></title>
<para>
Because the TIB (thread information block) is not fully described in the
MSDN, it might be possible that not all required TIB-parts are swapped. With
compiler flag <code><phrase role="identifier">BOOST_USE_WINFIBERS</phrase></code>
<code><phrase role="identifier">fiber</phrase></code> uses internally the
Windows Fiber API.
</para>
</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> creates for each thread a scheduler
( <link linkend="class_round_robin"> <code>round_robin</code></link>).
</para>
<para>
A fiber-scheduler must implement interface <link linkend="class_sched_algorithm"> <code>sched_algorithm</code></link>.
You are explicitly permitted to code your own <link linkend="class_sched_algorithm"> <code>sched_algorithm</code></link> subclass,
and to pass it to <link linkend="set_scheduling_algorithm"> <code>set_scheduling_algorithm()</code></link>.
</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>
<bridgehead renderas="sect4" id="class_sched_algorithm_bridgehead">
<phrase id="class_sched_algorithm"/>
<link linkend="class_sched_algorithm">Class
<code>sched_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">sched_algorithm</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="special">~</phrase><phrase role="identifier">sched_algorithm</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_context</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">fiber_context</phrase> <phrase role="special">*</phrase> <phrase role="identifier">pick_next</phrase><phrase role="special">()</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_awakened_bridgehead">
<phrase id="sched_algorithm_awakened"/>
<link linkend="sched_algorithm_awakened">Member
function <code>awakened</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_context</phrase> <phrase role="special">*</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>
Marks fiber <code><phrase role="identifier">f</phrase></code>, to be
ready to run.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_pick_next_bridgehead">
<phrase id="sched_algorithm_pick_next"/>
<link linkend="sched_algorithm_pick_next">Member
function <code>pick_next</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="identifier">fiber_context</phrase> <phrase role="special">*</phrase> <phrase role="identifier">pick_next</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>
Depending on the scheduling algorithm, this function returns the fiber
which is to be resumed next.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_priority_bridgehead">
<phrase id="sched_algorithm_priority"/>
<link linkend="sched_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">fiber_context</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="number">0</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Resets the priority of fiber <code><phrase role="identifier">f</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
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_sched_algorithm"> <code>sched_algorithm</code></link>.
<emphasis role="bold">Boost.Fiber</emphasis> provides one scheduler: <link linkend="class_round_robin"> <code>round_robin</code></link>.
</para>
<para>
You are explicitly permitted to code your own <link linkend="class_sched_algorithm"> <code>sched_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_sched_algorithm_bridgehead">
<phrase id="class_sched_algorithm"/>
<link linkend="class_sched_algorithm">Class
<code>sched_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">sched_algorithm</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="special">~</phrase><phrase role="identifier">sched_algorithm</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</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="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">pick_next</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">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="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="special">};</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_awakened_bridgehead">
<phrase id="sched_algorithm_awakened"/>
<link linkend="sched_algorithm_awakened">Member
function <code>awakened</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</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">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>
Marks fiber <code><phrase role="identifier">f</phrase></code>, to be
ready to run.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_pick_next_bridgehead">
<phrase id="sched_algorithm_pick_next"/>
<link linkend="sched_algorithm_pick_next">Member
function <code>pick_next</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">pick_next</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>
Depending on the scheduling algorithm, this function returns the fiber
which is to be resumed next.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="sched_algorithm_priority_bridgehead">
<phrase id="sched_algorithm_priority"/>
<link linkend="sched_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="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>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Resets the priority of fiber <code><phrase role="identifier">f</phrase></code>.
</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_sched_algorithm"> <code>sched_algorithm</code></link> and schedules fibers
in round-robin fashion (ignores <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">priority</phrase><phrase
role="special">()</phrase></code>).
</para>
<para>
[info The example section provides a scheduler used for migrating fibers (work-stealing)
between threads (different schedulers).]
</para>
<para>
&lt; TODO &gt;
</para>
<bridgehead renderas="sect3" id="fiber.scheduling.h0">
<phrase id="fiber.scheduling.customized_scheduler"/><link linkend="fiber.scheduling.customized_scheduler">customized
scheduler</link>
</bridgehead>
</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>execution_context</emphasis>
which manages a set of registers and a stack. The memory used by the stack
is allocated/deallocated via a __stack_allocator__ 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 __stack_allocator__ 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 __stack_allocator__
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">size</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
</entry>
<entry>
<para>
creates a stack allocator
</para>
</entry>
</row>
<row>
<entry>
<para>
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
role="identifier">allocate</phrase><phrase role="special">()</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="identifier">stack_context</phrase></code>
</para>
</entry>
<entry>
<para>
creates a stack
</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>execution_context</emphasis>.
</para>
</note>
<para>
<bridgehead renderas="sect4" id="class_protected_fixedsize_stack_bridgehead">
<phrase id="class_protected_fixedsize_stack"/>
<link linkend="class_protected_fixedsize_stack">Class
<code>protected_fixedsize_stack</code></link>
</bridgehead>
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides the class <link linkend="class_protected_fixedsize_stack"> <code>protected_fixedsize_stack</code></link> 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>
<important>
<para>
Using <link linkend="class_protected_fixedsize_stack"> <code>protected_fixedsize_stack</code></link> is expensive.
That is, launching a new fiber with a new stack is expensive; the allocated
stack is just as efficient to use as any other stack.
</para>
</important>
<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>
<para>
<bridgehead renderas="sect4" id="class_fixedsize_stack_bridgehead">
<phrase id="class_fixedsize_stack"/>
<link linkend="class_fixedsize_stack">Class
<code>fixedsize_stack</code></link>
</bridgehead>
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides the class <link linkend="class_fixedsize_stack"> <code>fixedsize_stack</code></link> which
models the <link linkend="stack_allocator_concept"><emphasis>stack-allocator
concept</emphasis></link>. In contrast to <link linkend="class_protected_fixedsize_stack"> <code>protected_fixedsize_stack</code></link> it
does not append a guard page at the end of each stack. The memory is simply
managed by <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">malloc</phrase><phrase role="special">()</phrase></code>
and <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">free</phrase><phrase role="special">()</phrase></code>.
</para>
<para>
<bridgehead renderas="sect4" id="class_segmented_stack_bridgehead">
<phrase id="class_segmented_stack"/>
<link linkend="class_segmented_stack">Class
<code>segmented_stack</code></link>
</bridgehead>
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> supports usage of a <link linkend="class_segmented_stack"> <code>segmented_stack</code></link>,
e. g. the size of the stack grows on demand. The fiber is created with a minimal
stack size and will be increased as required. Class <link linkend="class_segmented_stack"> <code>segmented_stack</code></link> models
the <link linkend="stack_allocator_concept"><emphasis>stack-allocator concept</emphasis></link>.
In contrast to <link linkend="class_protected_fixedsize_stack"> <code>protected_fixedsize_stack</code></link> and
<link linkend="class_fixedsize_stack"> <code>fixedsize_stack</code></link> it creates a stack which grows on demand.
</para>
<note>
<para>
Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
from version <emphasis role="bold">4.7</emphasis> <emphasis role="bold">clang</emphasis>
from version <emphasis role="bold">3.4</emphasis> onwards. In order to use
a <link linkend="class_segmented_stack"> <code>segmented_stack</code></link> <emphasis role="bold">Boost.Fiber</emphasis>
must be built with property <code><phrase role="identifier">segmented</phrase><phrase
role="special">-</phrase><phrase role="identifier">stacks</phrase></code>,
e.g. <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis> at
b2/bjam command line.
</para>
<para>
[endsect
</para>
</note>
</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="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">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">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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="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">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="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">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">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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="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="special">{</phrase>
<phrase role="identifier">std</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="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="special">}</phrase> <phrase role="comment">// release lk</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 <code><phrase role="identifier">data_ready</phrase></code>
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 <code><phrase
role="identifier">cond</phrase></code> 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">std</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>
Locking is important because the synchronization objects provided by <emphasis
role="bold">Boost.Fiber</emphasis> can be used to synchronize fibers running
on different threads.
</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">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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">std</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">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</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">std</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="special">{</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">pred</phrase><phrase role="special">();</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</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.channels">
<title><link linkend="fiber.synchronization.channels">Channels</link></title>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides a bounded and a unbounded
channel 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_channel</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">channel_t</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">send</phrase><phrase role="special">(</phrase> <phrase role="identifier">channel_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">channel</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="special">{</phrase>
<phrase role="identifier">channel</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="special">}</phrase>
<phrase role="identifier">channel</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">channel_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">channel</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">channel_op_status</phrase><phrase role="special">::</phrase><phrase role="identifier">success</phrase> <phrase role="special">==</phrase> <phrase role="identifier">channel</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">channel_t</phrase> <phrase role="identifier">channel</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">std</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">channel</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">std</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">channel</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_channel_op_status"/>
<bridgehead renderas="sect4" id="fiber.synchronization.channels.h0">
<phrase id="fiber.synchronization.channels.enumeration__code__phrase_role__identifier__channel_op_status__phrase___code_"/><link
linkend="fiber.synchronization.channels.enumeration__code__phrase_role__identifier__channel_op_status__phrase___code_">Enumeration
<code><phrase role="identifier">channel_op_status</phrase></code></link>
</bridgehead>
<para>
channel operations return the state of the channel.
</para>
<programlisting><phrase role="keyword">enum</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">channel_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.channels.h1">
<phrase id="fiber.synchronization.channels._code__phrase_role__identifier__success__phrase___code_"/><link
linkend="fiber.synchronization.channels._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.channels.h2">
<phrase id="fiber.synchronization.channels._code__phrase_role__identifier__empty__phrase___code_"/><link
linkend="fiber.synchronization.channels._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>
channel is empty, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.channels.h3">
<phrase id="fiber.synchronization.channels._code__phrase_role__identifier__full__phrase___code_"/><link
linkend="fiber.synchronization.channels._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>
channel is full, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.channels.h4">
<phrase id="fiber.synchronization.channels._code__phrase_role__identifier__closed__phrase___code_"/><link
linkend="fiber.synchronization.channels._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>
channel is closed, operation failed.
</para>
</listitem>
</varlistentry>
</variablelist>
<bridgehead renderas="sect4" id="fiber.synchronization.channels.h5">
<phrase id="fiber.synchronization.channels._code__phrase_role__identifier__timeout__phrase___code_"/><link
linkend="fiber.synchronization.channels._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_channel_bridgehead">
<phrase id="class_unbounded_channel"/>
<link linkend="class_unbounded_channel">Template
<code>unbounded_channel&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_channel</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_channel</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_channel</phrase><phrase role="special">(</phrase> <phrase role="identifier">unbounded_channel</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_channel</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">unbounded_channel</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="identifier">channel_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="identifier">channel_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="identifier">value_type</phrase> <phrase role="identifier">value_pop</phrase><phrase role="special">();</phrase>
<phrase role="identifier">channel_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="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">channel_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">std</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="unbounded_channel_is_closed_bridgehead">
<phrase id="unbounded_channel_is_closed"/>
<link linkend="unbounded_channel_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 channel has been
closed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The channel is not closed by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_channel_close_bridgehead">
<phrase id="unbounded_channel_close"/>
<link linkend="unbounded_channel_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 channel. 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_channel_is_empty_bridgehead">
<phrase id="unbounded_channel_is_empty"/>
<link linkend="unbounded_channel_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 channel
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> channel can become non-empty.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_channel_push_bridgehead">
<phrase id="unbounded_channel_push"/>
<link linkend="unbounded_channel_push">Member
function <code>push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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>
Enchannels the value in the channel 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_channel_pop_bridgehead">
<phrase id="unbounded_channel_pop"/>
<link linkend="unbounded_channel_pop">Member
function <code>pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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>
Dechannels a value from the channel. If the channel <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 dechanneld
value) or the channel 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_channel_value_pop_bridgehead">
<phrase id="unbounded_channel_value_pop"/>
<link linkend="unbounded_channel_value_pop">Member
function <code>value_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">value_type</phrase> <phrase role="identifier">value_pop</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dechannels a value from the channel. If the channel <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 or the channel gets <code><phrase
role="identifier">close</phrase><phrase role="special">()</phrase></code>d
(which throws an exception).
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">logic_error</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
is closed; <code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_channel_try_pop_bridgehead">
<phrase id="unbounded_channel_try_pop"/>
<link linkend="unbounded_channel_try_pop">Member
function <code>try_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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
dechanneld value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="unbounded_channel_pop_wait_for_bridgehead">
<phrase id="unbounded_channel_pop_wait_for"/>
<link linkend="unbounded_channel_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">channel_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">std</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">std</phrase><phrase role="special">::</phrase><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 dechannels a value from the channel. 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 dechanneld
value), or the channel 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_channel_pop_wait_until_bridgehead">
<phrase id="unbounded_channel_pop_wait_until"/>
<link linkend="unbounded_channel_pop_wait_until">Member
function <code>pop_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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">time_point</phrase><phrase role="special">&lt;</phrase>
<phrase role="identifier">Clock</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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 dechannels a value
from the channel. 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 dechanneld
value), or the channel 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="class_bounded_channel_bridgehead">
<phrase id="class_bounded_channel"/>
<link linkend="class_bounded_channel">Template
<code>bounded_channel&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_channel</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_channel</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_channel</phrase><phrase role="special">(</phrase> <phrase role="identifier">bounded_channel</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_channel</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">bounded_channel</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_channel</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_channel</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="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">upper_bound</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lower_bound</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</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">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_full</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">channel_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">channel_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">channel_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">std</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">channel_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">std</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">channel_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">channel_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">value_type</phrase> <phrase role="identifier">value_pop</phrase><phrase role="special">();</phrase>
<phrase role="identifier">channel_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">channel_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">std</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="identifier">channel_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.channels.h6">
<phrase id="fiber.synchronization.channels.constructor"/><link linkend="fiber.synchronization.channels.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">bounded_channel</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_channel</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_channel</phrase></code>.
The constructor with two arguments constructs an object of class <code><phrase
role="identifier">bounded_channel</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 channel 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 channel 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 channel 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 channel is less than <code><phrase
role="identifier">hwm</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_upper_bound_bridgehead">
<phrase id="bounded_channel_upper_bound"/>
<link linkend="bounded_channel_upper_bound">Member
function <code>upper_bound</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">upper_bound</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 high-watermark with which <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> was constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_lower_bound_bridgehead">
<phrase id="bounded_channel_lower_bound"/>
<link linkend="bounded_channel_lower_bound">Member
function <code>lower_bound</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lower_bound</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 low-watermark with which <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> was constructed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_is_closed_bridgehead">
<phrase id="bounded_channel_is_closed"/>
<link linkend="bounded_channel_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 channel has been
closed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The channel is not closed by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_close_bridgehead">
<phrase id="bounded_channel_close"/>
<link linkend="bounded_channel_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 channel. 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_channel_is_empty_bridgehead">
<phrase id="bounded_channel_is_empty"/>
<link linkend="bounded_channel_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> <phrase role="keyword">const</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 channel
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> channel can become non-empty.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_is_full_bridgehead">
<phrase id="bounded_channel_is_full"/>
<link linkend="bounded_channel_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> <phrase role="keyword">const</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 channel
cannot accept more data at present. This happens when the number of
values in the channel reaches <code><phrase role="identifier">wm</phrase></code>
or <code><phrase role="identifier">hwm</phrase></code>. Once the channel
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_channel_push_bridgehead">
<phrase id="bounded_channel_push"/>
<link linkend="bounded_channel_push">Member
function <code>push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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">channel_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>, enchannels the value in the channel,
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
channel drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
or the channel 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_channel_push_wait_for_bridgehead">
<phrase id="bounded_channel_push_wait_for"/>
<link linkend="bounded_channel_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">channel_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">std</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">channel_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">std</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">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">duration</phrase></code> and internally computes
a time_point as <code><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>, enchannels the value in the channel,
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 calling fiber is suspended until the number of values
in the channel drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
the channel 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">now</phrase><phrase
role="special">()</phrase></code> reaches the computed time_point (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_channel_push_wait_until_bridgehead">
<phrase id="bounded_channel_push_wait_until"/>
<link linkend="bounded_channel_push_wait_until">Member
function <code>push_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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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 an absolute <code><phrase role="identifier">timeout_time</phrase></code>
in any supported time_point type. 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>, enchannels the value in the channel,
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 calling fiber is suspended until the number of values
in the channel drops below <code><phrase role="identifier">lwm</phrase></code>
(return value <code><phrase role="identifier">success</phrase></code>),
the channel 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">now</phrase><phrase
role="special">()</phrase></code> reaches the passed time_point (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_channel_try_push_bridgehead">
<phrase id="bounded_channel_try_push"/>
<link linkend="bounded_channel_try_push">Member
function <code>try_push</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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">channel_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
enchannels the value in the channel, 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_channel_pop_bridgehead">
<phrase id="bounded_channel_pop"/>
<link linkend="bounded_channel_pop">Member
function <code>pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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>
Dechannels a value from the channel. If the channel <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 dechanneld
value) or the channel 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 channel 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_channel_value_pop_bridgehead">
<phrase id="bounded_channel_value_pop"/>
<link linkend="bounded_channel_value_pop">Member
function <code>value_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">value_type</phrase> <phrase role="identifier">value_pop</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dechannels a value from the channel. If the channel <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 or the channel gets <code><phrase
role="identifier">close</phrase><phrase role="special">()</phrase></code>d
(which throws an exception). Once the number of items remaining in
the channel 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">logic_error</phrase></code> if <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>
is closed; <code><phrase role="identifier">fiber_interrupted</phrase></code>
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_try_pop_bridgehead">
<phrase id="bounded_channel_try_pop"/>
<link linkend="bounded_channel_try_pop">Member
function <code>try_pop</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="identifier">channel_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
dechanneld value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="bounded_channel_pop_wait_for_bridgehead">
<phrase id="bounded_channel_pop_wait_for"/>
<link linkend="bounded_channel_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">channel_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">std</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">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase
role="identifier">duration</phrase></code> and internally computes
a time_point as <code><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 dechannels a value
from the channel. Otherwise the calling 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 dechanneld
value), or the channel 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">now</phrase><phrase
role="special">()</phrase></code> reaches the computed time_point (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_channel_pop_wait_until_bridgehead">
<phrase id="bounded_channel_pop_wait_until"/>
<link linkend="bounded_channel_pop_wait_until">Member
function <code>pop_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">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">channel_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">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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 an absolute <code><phrase role="identifier">timeout_time</phrase></code>
in any supported time_point type. 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 dechannels a value from the channel. Otherwise the calling
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 dechanneld
value), or the channel 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">now</phrase><phrase
role="special">()</phrase></code> reaches the passed time_point (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>
</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">std</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="comment">// not supported yet</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>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Not implemented yet.
</para>
</listitem>
</varlistentry>
</variablelist>
<warning>
<para>
Launch policy <code><phrase role="identifier">deferred</phrase></code>,
which indicates you simply want to defer the function call until a later
time (lazy evaluation), is not supported yet.
</para>
</warning>
<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="comment">// member only of generic future template</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of future&lt; R &amp; &gt; template specialization</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of future&lt; void &gt; template specialization</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">std</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="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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> <phrase role="comment">// member only of generic future template</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of future&lt; R &amp; &gt; template specialization</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of future&lt; void &gt; template specialization</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">std</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="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of generic shared_future template</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of shared_future&lt; R &amp; &gt; template specialization</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of shared_future&lt; void &gt; template specialization</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">std</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="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of generic shared_future template</phrase>
<phrase role="identifier">R</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of shared_future&lt; R &amp; &gt; template specialization</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase> <phrase role="comment">// member only of shared_future&lt; void &gt; template specialization</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">std</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="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Clock</phrase><phrase role="special">,</phrase> <phrase role="identifier">Duration</phrase> <phrase role="special">&gt;</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="fibers_async_bridgehead">
<phrase id="fibers_async"/>
<link linkend="fibers_async">Non-member function <code>fibers::async()</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">future</phrase><phrase role="special">/</phrase><phrase role="identifier">async</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">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">result_of</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">async</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>
Executes <code><phrase role="identifier">fn</phrase></code> in a
fiber and returns an associated future.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
<code><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase>
<phrase role="keyword">typename</phrase> <phrase role="identifier">result_of</phrase><phrase
role="special">&lt;</phrase> <phrase role="identifier">Fn</phrase>
<phrase role="special">&gt;::</phrase><phrase role="identifier">type</phrase>
<phrase role="special">&gt;</phrase></code> representing the shared
state associated with the asynchronous execution of <code><phrase
role="identifier">fn</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> or
<code><phrase role="identifier">future_error</phrase></code> if an
error occurs.
</para>
</listitem>
</varlistentry>
</variablelist>
<warning>
<para>
Launch policy <code><phrase role="identifier">deferred</phrase></code>,
which indicates you simply want to defer the function call until a later
time (lazy evaluation), is not supported yet.
</para>
</warning>
</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">std</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">std</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">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="special">...</phrase> <phrase role="identifier">Args</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="identifier">Args</phrase> <phrase role="special">...</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">std</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="identifier">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</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">std</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> <phrase role="identifier">Args</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="special">...</phrase> <phrase role="identifier">args</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.performance">
<title><link linkend="fiber.performance">Performance</link></title>
<para>
Performance measurements were taken using <code><phrase role="identifier">std</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, optimization = speed <footnote id="fiber.performance.f0">
<para>
Intel Core2 Q6700, x86_64, 3GHz
</para>
</footnote>.
</para>
<table frame="all" id="fiber.performance.overhead_of_creating_and_joining">
<title>Overhead of creating and joining</title>
<tgroup cols="4">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
<entry>
<para>
tbb
</para>
</entry>
<entry>
<para>
qthread
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
31 &#xb5;s
</para>
</entry>
<entry>
<para>
1.1 &#xb5;s
</para>
</entry>
<entry>
<para>
570 ns
</para>
</entry>
<entry>
<para>
620 ns
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_detach">
<title>Overhead of detach</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
20 &#xb5;s
</para>
</entry>
<entry>
<para>
3.2 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_yield">
<title>Overhead of yield</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
38 &#xb5;s
</para>
</entry>
<entry>
<para>
1.3 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_waiting_on_a_future">
<title>Overhead of waiting on a future</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
32 &#xb5;s
</para>
</entry>
<entry>
<para>
3.0 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.scaling_of_creating_and_joining">
<title>Scaling of creating and joining</title>
<tgroup cols="3">
<thead>
<row>
<entry>
<para>
average of
</para>
</entry>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
10
</para>
</entry>
<entry>
<para>
50.65 &#xb5;s
</para>
</entry>
<entry>
<para>
4.83 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
50
</para>
</entry>
<entry>
<para>
52.99 &#xb5;s
</para>
</entry>
<entry>
<para>
4.84 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
100
</para>
</entry>
<entry>
<para>
50.44 &#xb5;s
</para>
</entry>
<entry>
<para>
5.24 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
500
</para>
</entry>
<entry>
<para>
45.19 &#xb5;s
</para>
</entry>
<entry>
<para>
4.86 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
1000
</para>
</entry>
<entry>
<para>
42.59 &#xb5;s
</para>
</entry>
<entry>
<para>
5.04 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
5000
</para>
</entry>
<entry>
<para>
42.30 &#xb5;s
</para>
</entry>
<entry>
<para>
5.07 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
10000
</para>
</entry>
<entry>
<para>
41.07 &#xb5;s
</para>
</entry>
<entry>
<para>
5.12 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
Using internally atomics by applying BOOST_FIBER_NO_ATOMICS.
</para>
<table frame="all" id="fiber.performance.overhead_of_creating_and_joinin0">
<title>Overhead of creating and joining</title>
<tgroup cols="4">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
<entry>
<para>
tbb
</para>
</entry>
<entry>
<para>
qthread
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
31 &#xb5;s
</para>
</entry>
<entry>
<para>
955 ns
</para>
</entry>
<entry>
<para>
570 ns
</para>
</entry>
<entry>
<para>
620 ns
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_detach0">
<title>Overhead of detach</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
20 &#xb5;s
</para>
</entry>
<entry>
<para>
3.2 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_yield0">
<title>Overhead of yield</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
38 &#xb5;s
</para>
</entry>
<entry>
<para>
1.1 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.overhead_of_waiting_on_a_future0">
<title>Overhead of waiting on a future</title>
<tgroup cols="2">
<thead>
<row>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
32 &#xb5;s
</para>
</entry>
<entry>
<para>
2.4 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
<table frame="all" id="fiber.performance.scaling_of_creating_and_joining0">
<title>Scaling of creating and joining</title>
<tgroup cols="3">
<thead>
<row>
<entry>
<para>
average of
</para>
</entry>
<entry>
<para>
thread
</para>
</entry>
<entry>
<para>
fiber
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
10
</para>
</entry>
<entry>
<para>
50.65 &#xb5;s
</para>
</entry>
<entry>
<para>
3.76 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
50
</para>
</entry>
<entry>
<para>
52.99 &#xb5;s
</para>
</entry>
<entry>
<para>
2.78 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
100
</para>
</entry>
<entry>
<para>
50.44 &#xb5;s
</para>
</entry>
<entry>
<para>
2.45 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
500
</para>
</entry>
<entry>
<para>
45.19 &#xb5;s
</para>
</entry>
<entry>
<para>
2.91 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
1000
</para>
</entry>
<entry>
<para>
42.59 &#xb5;s
</para>
</entry>
<entry>
<para>
3.60 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
5000
</para>
</entry>
<entry>
<para>
42.30 &#xb5;s
</para>
</entry>
<entry>
<para>
4.57 &#xb5;s
</para>
</entry>
</row>
<row>
<entry>
<para>
10000
</para>
</entry>
<entry>
<para>
41.07 &#xb5;s
</para>
</entry>
<entry>
<para>
4.21 &#xb5;s
</para>
</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
<section id="fiber.rational">
<title><link linkend="fiber.rational">Rational</link></title>
<bridgehead renderas="sect3" id="fiber.rational.h0">
<phrase id="fiber.rational.distinction_between_coroutines_and_fibers"/><link
linkend="fiber.rational.distinction_between_coroutines_and_fibers">Distinction
between coroutines and fibers</link>
</bridgehead>
<para>
The fiber library extends the coroutine library by adding a scheduler and synchronization
mechanisms.
</para>
<programlisting><phrase role="special">*</phrase> <phrase role="identifier">a</phrase> <phrase role="identifier">coroutine</phrase> <phrase role="identifier">yields</phrase>
<phrase role="special">*</phrase> <phrase role="identifier">a</phrase> <phrase role="identifier">fiber</phrase> <phrase role="identifier">blocks</phrase>
</programlisting>
<para>
When a coroutine yields, it passes control directly to its caller (or, in the
case of symmetric coroutines, a designated other coroutine). When a fiber blocks,
it implicitly passes control to the fiber scheduler. Coroutines have no scheduler
because they need no scheduler. <footnote id="fiber.rational.f0">
<para>
<ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4024.pdf">'N4024:
Distinguishing coroutines and fibers'</ulink>
</para>
</footnote>.
</para>
<bridgehead renderas="sect3" id="fiber.rational.h1">
<phrase id="fiber.rational.what_about_transactional_memory"/><link linkend="fiber.rational.what_about_transactional_memory">what
about transactional memory</link>
</bridgehead>
<para>
GCC support transactional memory since version 4.7. Unfortunately testes showed
that transactional memory is slower (ca. 4x) than using spinlocks using atomics.
If transactional memory will be improved (supporting hybrid tm), spinlocks
will be replaced by __transaction_atomic{} statements surrounding the critical
sections.
</para>
<bridgehead renderas="sect3" id="fiber.rational.h2">
<phrase id="fiber.rational.synchronization_between_fibers_running_in_different_threads"/><link
linkend="fiber.rational.synchronization_between_fibers_running_in_different_threads">synchronization
between fibers running in different threads</link>
</bridgehead>
<para>
Synchronization classes from <ulink url="boost:/libs/thread/index.html">Boost.Thread</ulink>
do block the entire thread. In contrast to this the synchronization clases
from <emphasis role="bold">Boost.Fiber</emphasis> do block only the fiber,
so that the thread is able to schedule and run other fibers in the meantime.
The synchronization classes from <emphasis role="bold">Boost.Fiber</emphasis>
are designed to be thread-safe, e.g. it is possible to synchronize fibers running
in different schedulers (different threads) or running int the same scheduler
(same thread).
</para>
</section>
<section id="fiber.custom">
<title><link linkend="fiber.custom">Customization</link></title>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> allows to customize the scheduling
algorithm by a user-defined implementation. A fiber-scheduler must implement
interface <link linkend="class_sched_algorithm"> <code>sched_algorithm</code></link>. <emphasis role="bold">Boost.Fiber</emphasis>
provides scheduler <link linkend="class_round_robin"> <code>round_robin</code></link>.
</para>
<para>
In order to use a custom 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>
You are explicitly permitted to code your own <link linkend="class_sched_algorithm"> <code>sched_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_sched_algorithm_bridgehead">
<phrase id="class_sched_algorithm"/>
<link linkend="class_sched_algorithm">Class
<code>sched_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">sched_algorithm</phrase> <phrase role="special">{</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="special">~</phrase><phrase role="identifier">sched_algorithm</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_context</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">fiber_context</phrase> <phrase role="special">*</phrase> <phrase role="identifier">pick_next</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">sched_algorithm</phrase> <phrase role="special">*);</phrase>
</programlisting>
<para>
<bridgehead renderas="sect4" id="algorithm_awakened_bridgehead">
<phrase id="algorithm_awakened"/>
<link linkend="algorithm_awakened">Member function
<code>awakened</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="keyword">void</phrase> <phrase role="identifier">awakened</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_context</phrase> <phrase role="special">*</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>
Marks fiber <code><phrase role="identifier">f</phrase></code>, to be
ready to run.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="algorithm_pick_next_bridgehead">
<phrase id="algorithm_pick_next"/>
<link linkend="algorithm_pick_next">Member
function <code>pick_next</code>()</link>
</bridgehead>
</para>
<programlisting><phrase role="keyword">virtual</phrase> <phrase role="identifier">fiber_context</phrase> <phrase role="special">*</phrase> <phrase role="identifier">pick_next</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>
Depending on the scheduling algorithm, this function returns the fiber
which has to be resumed next.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
<bridgehead renderas="sect4" id="fibers_set_scheduling_algorithm_bridgehead">
<phrase id="fibers_set_scheduling_algorithm"/>
<link linkend="fibers_set_scheduling_algorithm">Non-member
function <code>fibers::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">sched_algorithm</phrase> <phrase role="special">*</phrase> <phrase role="identifier">a</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Registers <code><phrase role="identifier">a</phrase></code> as scheduling
algorithm.
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
&lt; TODO &gt;
</para>
</section>
<section id="fiber.acknowledgements">
<title><link linkend="fiber.acknowledgements">Acknowledgments</link></title>
<para>
I'd like to thank Eugene Yakubovich and especially Nat Goodspeed.
</para>
</section>
</library>