2
0
mirror of https://github.com/boostorg/fiber.git synced 2026-02-20 02:32:19 +00:00
Files
fiber/doc/fibers.xml
2013-10-26 10:31:23 +02:00

6667 lines
431 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: 2013/10/26 08:30:32 $"
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>
<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 <emphasis role="bold">Boost.Thread</emphasis>.
</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). 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>
<anchor id="fiber.overview.fibers_and_threads"/>
<bridgehead renderas="sect3">
<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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>.
</para>
<anchor id="fiber.overview.blocking"/>
<bridgehead renderas="sect3">
<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 <code><phrase role="identifier">future</phrase></code> 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. <emphasis role="bold">Boost.Asio</emphasis> 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 <emphasis role="bold">Boost.Chrono</emphasis>,
<emphasis role="bold">Boost.Coroutine</emphasis> and <emphasis role="bold">Boost.Move</emphasis>.
Boost version 1.55.0 or greater is required.
</para>
</section>
<section id="fiber.fiber_mgmt">
<title><link linkend="fiber.fiber_mgmt">Fiber management</link></title> <anchor
id="fiber.fiber_mgmt.synopsis"/>
<bridgehead renderas="sect3">
<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="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber_group</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">algorithm</phrase><phrase role="special">;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">round_robin</phrase><phrase role="special">;</phrase>
<phrase role="identifier">algorithm</phrase> <phrase role="special">*</phrase> <phrase role="identifier">set_scheduling_algorithm</phrase><phrase role="special">(</phrase> <phrase role="identifier">algorithm</phrase> <phrase role="special">*</phrase> <phrase role="identifier">al</phrase><phrase role="special">)</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">namespace</phrase> <phrase role="identifier">this_fiber</phrase> <phrase role="special">{</phrase>
<phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase> <phrase role="identifier">get_id</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_point</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interruption_point</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_requested</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase> <phrase role="identifier">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>
<anchor id="fiber.fiber_mgmt.tutorial"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.tutorial">Tutorial</link>
</bridgehead>
<para>
Each <code><phrase role="identifier">fiber</phrase></code> represents a micro-thread
which will be launched and managed cooperatively by a scheduler. Objects of
type <code><phrase role="identifier">fiber</phrase></code> are only moveable.
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">;</phrase> <phrase role="comment">// not-a-fiber
</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">f</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase> <phrase role="identifier">some_fn</phrase><phrase role="special">);</phrase>
<phrase role="identifier">f1</phrase> <phrase role="special">=</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase> <phrase role="identifier">f2</phrase><phrase role="special">);</phrase> <phrase role="comment">// f2 moved to f1
</phrase><phrase role="special">}</phrase>
</programlisting>
<anchor id="fiber.fiber_mgmt.launching"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.launching">Launching</link>
</bridgehead>
<important>
<para>
Each thread must first set the fiber-scheduler before any <code><phrase role="identifier">fiber</phrase></code>
construction.
</para>
</important>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">round_robin</phrase> <phrase role="identifier">ds</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">ds</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">some_fn</phrase><phrase role="special">);</phrase>
</programlisting>
<important>
<para>
Oliver: I think there should be a reference section on <code><phrase role="identifier">algorithm</phrase></code>,
<code><phrase role="identifier">round_robin</phrase></code> and <code><phrase
role="identifier">set_scheduling_algorithm</phrase></code>. It need not say
much at this point -- although since right now the only provided <code><phrase
role="identifier">algorithm</phrase></code> is <code><phrase role="identifier">round_robin</phrase></code>,
it would be great if you would explain how to provide a custom <code><phrase
role="identifier">algorithm</phrase></code>. I've added a note to the <code><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">priority</phrase><phrase role="special">()</phrase></code>
method explaining that <code><phrase role="identifier">round_robin</phrase></code>
disregards <code><phrase role="identifier">priority</phrase><phrase role="special">()</phrase></code>.
</para>
</important>
<para>
A new fiber is launched by passing an object of a callable type that can be
invoked with no parameters. If the object must not (or cannot) be copied, then
<emphasis>boost::ref</emphasis> can be used to pass in a reference to the function
object. In this case, the user must ensure that the referenced object outlives
the newly-created fiber.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">callable</phrase>
<phrase role="special">{</phrase> <phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase> <phrase role="special">};</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">copies_are_safe</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">callable</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">x</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// x is destroyed, but the newly-created fiber has a copy, so this is OK
</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">oops</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">callable</phrase> <phrase role="identifier">x</phrase><phrase role="special">;</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">x</phrase><phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// x is destroyed, but the newly-created fiber still has a reference
</phrase> <phrase role="comment">// this leads to undefined behaviour
</phrase></programlisting>
<para>
Control is immediately transferred to the spawned <code><phrase role="identifier">fiber</phrase></code>
at construction. When the constructor returns, the <code><phrase role="identifier">fiber</phrase></code>
might be complete or might have suspended.
</para>
<anchor id="fiber.fiber_mgmt.exceptions"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.exceptions">Exceptions</link>
</bridgehead>
<para>
Exceptions thrown by the function or callable object passed to the <code><phrase
role="identifier">fiber</phrase></code> constructor are consumed by the framework.
If you need to know which exception was thrown, use <code><phrase role="identifier">future</phrase></code>
and <code><phrase role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code>.
</para>
<anchor id="fiber.fiber_mgmt.detaching"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.detaching">Detaching</link>
</bridgehead>
<para>
A <code><phrase role="identifier">fiber</phrase></code> can be detached by
explicitly invoking the <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">detach</phrase><phrase
role="special">()</phrase></code> member function. After <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">detach</phrase><phrase
role="special">()</phrase></code> 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>
<anchor id="fiber.fiber_mgmt.joining"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.joining">Joining</link>
</bridgehead>
<para>
In order to wait for a fiber to finish, the <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
member function of the <code><phrase role="identifier">fiber</phrase></code>
object can be used. <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">join</phrase><phrase role="special">()</phrase></code> will
block until the <code><phrase role="identifier">fiber</phrase></code> object
has completed. If the <code><phrase role="identifier">fiber</phrase></code>
has already completed, or the <code><phrase role="identifier">fiber</phrase></code>
object represents <emphasis>not-a-fiber</emphasis>, then <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
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 <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
returns immediately and the joined <code><phrase role="identifier">fiber</phrase></code>
object becomes <emphasis>not-a-fiber</emphasis>.
</para>
<anchor id="fiber.fiber_mgmt.destruction"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.destruction">Destruction</link>
</bridgehead>
<para>
When a <code><phrase role="identifier">fiber</phrase></code> object representing
a valid execution context is destroyed, the program terminates if the fiber
is <code><phrase role="identifier">joinable</phrase></code>. If you intend
the fiber to outlive the <code><phrase role="identifier">fiber</phrase></code>
object that launched it, use the <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">detach</phrase><phrase
role="special">()</phrase></code> 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="fiber.fiber_mgmt.interruption"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.interruption">Interruption</link>
</bridgehead>
<para>
A valid fiber can be interrupted by invoking its <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interrupt</phrase><phrase
role="special">()</phrase></code> member function. The next time that fiber
executes one of the specific <emphasis>interruption-points</emphasis> 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 <code><phrase role="identifier">disable_interruption</phrase></code> 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 <code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>.
The following <emphasis>interruption-points</emphasis> are defined and will
throw <code><phrase role="identifier">fiber_interrupted</phrase></code> if
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_requested</phrase><phrase role="special">()</phrase></code>
and <code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>.
</para>
<itemizedlist>
<listitem>
<simpara>
<code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">join</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">barrier</phrase><phrase role="special">::</phrase><phrase
role="identifier">wait</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">condition</phrase><phrase role="special">::</phrase><phrase
role="identifier">wait</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">condition</phrase><phrase role="special">::</phrase><phrase
role="identifier">wait_for</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">condition</phrase><phrase role="special">::</phrase><phrase
role="identifier">wait_until</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">barrier</phrase><phrase role="special">::</phrase><phrase
role="identifier">wait</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">sleep_for</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">sleep_until</phrase><phrase role="special">()</phrase></code>
</simpara>
</listitem>
<listitem>
<simpara>
<code><phrase role="identifier">interruption_point</phrase></code>
</simpara>
</listitem>
</itemizedlist>
<important>
<para>
Oliver: why isn't yield() an interruption point?
</para>
</important>
<anchor id="fiber.fiber_mgmt.fiber_ids"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fiber_mgmt.fiber_ids">Fiber IDs</link>
</bridgehead>
<para>
Objects of class <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code> can be used to identify fibers. Each running
<code><phrase role="identifier">fiber</phrase></code> has a unique <code><phrase
role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase role="identifier">id</phrase></code>
obtainable from the corresponding <code><phrase role="identifier">fiber</phrase></code>
by calling the <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>
member function. Objects of class <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code> 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 <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code> 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 <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code> yield a total order for every non-equal
<code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code>.
</para>
<section id="fiber.fiber_mgmt.fiber">
<title><link linkend="fiber.fiber_mgmt.fiber">Class <code><phrase role="identifier">fiber</phrase></code></link></title>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">uspecified</phrase><phrase role="special">-</phrase><phrase role="keyword">class</phrase> <phrase role="identifier">id</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">stack_allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="special">~</phrase><phrase role="identifier">fiber</phrase><phrase role="special">();</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">int</phrase> <phrase role="identifier">priority</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">detach</phrase><phrase role="special">()</phrase> <phrase role="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">&lt;(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">l</phrase><phrase role="special">,</phrase> <phrase role="identifier">fiber</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">r</phrase><phrase role="special">)</phrase> <phrase role="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<anchor id="fiber.fiber_mgmt.fiber.default_constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.default_constructor">Default constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs a <code><phrase role="identifier">fiber</phrase></code>
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>
<anchor id="fiber.fiber_mgmt.fiber.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">stack_allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase> <phrase role="special">=</phrase> <phrase role="identifier">stack_allocator</phrase><phrase role="special">(),</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase> <phrase role="special">=</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">&gt;()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">attr</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">Fn</phrase></code> must be copyable
or movable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
<code><phrase role="identifier">fn</phrase></code> is copied into internal
storage for access by the new fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
refers to the newly created fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_exception</phrase></code> if
an error occurs.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
StackAllocator is required to allocate a stack for the internal coroutine.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.move_constructor"/>
<bridgehead renderas="sect4">
<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="identifier">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 <code><phrase role="identifier">fiber</phrase></code>
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>
<anchor id="fiber.fiber_mgmt.fiber.move_assignment_operator"/>
<bridgehead renderas="sect4">
<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="identifier">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>
<anchor id="fiber.fiber_mgmt.fiber.destructor"/>
<bridgehead renderas="sect4">
<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 joinable, 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 joinable. See <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">detach</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__joinable__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__joinable__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">joinable</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">joinable</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__join__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__join__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 joinable.
</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 joinable.
</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 <emphasis>interruption-points</emphasis>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__detach__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__detach__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">detach</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 joinable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The fiber of execution becomes detached, and no longer has an associated
<code><phrase role="identifier">fiber</phrase></code> 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 joinable.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__get_id__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__get_id__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get_id</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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 <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code>
that represents that fiber. Otherwise returns a default-constructed
<code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">id</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__interrupt__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__interrupt__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">interrupt</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <emphasis>interruption-points</emphasis>
with interruption enabled, or if it is currently <emphasis>blocked</emphasis>
in a call to one of the predefined <emphasis>interruption-points</emphasis>
with interruption enabled.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special_____phrase___phrase_role__keyword__int__phrase__phrase_role__special_____phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special_____phrase___phrase_role__keyword__int__phrase__phrase_role__special_____phrase___code_">Member
function <code><phrase role="identifier">priority</phrase><phrase role="special">(</phrase>
<phrase role="keyword">int</phrase><phrase role="special">)</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">priority</phrase><phrase role="special">(</phrase> <phrase role="keyword">int</phrase><phrase role="special">)</phrase> <phrase role="identifier">noexcept</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, set its priority.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The meaning of particular <code><phrase role="keyword">int</phrase></code>
values is determined by the specific <code><phrase role="identifier">algorithm</phrase></code>
passed to <code><phrase role="identifier">set_scheduling_algorithm</phrase><phrase
role="special">()</phrase></code>. <code><phrase role="identifier">round_robin</phrase></code>
ignores <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">priority</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__priority__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">priority</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">priority</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">noexcept</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, return its priority.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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, <code><phrase role="keyword">false</phrase></code>
otherwise. In effect, this is synonymous with <code><phrase role="identifier">joinable</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">!()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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, <code><phrase role="keyword">false</phrase></code>
otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.fiber_mgmt.fiber.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber.non_member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
</section>
<section id="fiber.fiber_mgmt.fiber_group">
<title><link linkend="fiber.fiber_mgmt.fiber_group">Class <code><phrase role="identifier">fiber_group</phrase></code></link></title>
<para>
<code><phrase role="identifier">fiber_group</phrase></code> represents a
collection of fibers which can be collectively waited on or interrupted.
<code><phrase role="identifier">fiber_group</phrase></code> is neither copyable
nor movable.
</para>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">fiber_group</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">fiber_group</phrase><phrase role="special">()</phrase> <phrase role="special">{}</phrase>
<phrase role="special">~</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
<phrase role="identifier">fiber_group</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber_group</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">fiber_group</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">fiber_group</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">is_fiber_in</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">remove_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">join_all</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">interrupt_all</phrase><phrase role="special">();</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.fiber_mgmt.fiber_group.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Create a new fiber group with no fibers.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.destructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">fiber_group</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Destroy <code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
and <code><phrase role="keyword">delete</phrase></code> all <code><phrase
role="identifier">fiber</phrase></code> objects in the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: you don't <code><phrase role="keyword">delete</phrase></code>
a <code><phrase role="identifier">fiber</phrase></code> object, you
<code><phrase role="keyword">delete</phrase></code> a <code><phrase
role="identifier">fiber</phrase><phrase role="special">*</phrase></code>.
Maybe something like: &quot;Destroy <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> and all <code><phrase role="identifier">fiber</phrase></code>
objects in the group.&quot; ?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__create_fiber__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__create_fiber__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">create_fiber</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="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase> <phrase role="special">=</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">StackAllocator</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">create_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="identifier">fn</phrase><phrase role="special">,</phrase> <phrase role="identifier">attributes</phrase> <phrase role="identifier">attrs</phrase><phrase role="special">,</phrase>
<phrase role="identifier">StackAllocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">stack_alloc</phrase><phrase role="special">,</phrase>
<phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Create a new <code><phrase role="identifier">fiber</phrase></code>
object as-if by <code><phrase role="keyword">new</phrase> <phrase role="identifier">fiber</phrase><phrase
role="special">(</phrase> <phrase role="identifier">fn</phrase><phrase
role="special">)</phrase></code> and add it to the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is increased by one, the new fiber is running.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
A pointer to the new <code><phrase role="identifier">fiber</phrase></code>
object.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__add_fiber__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__add_fiber__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">add_fiber</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
The expression <code><phrase role="keyword">delete</phrase> <phrase
role="identifier">f</phrase></code> is well-formed and will not result
in undefined behaviour and <code><phrase role="identifier">is_fiber_in</phrase><phrase
role="special">(</phrase><phrase role="identifier">f</phrase><phrase
role="special">)</phrase> <phrase role="special">==</phrase> <phrase
role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Take ownership of the <code><phrase role="identifier">fiber</phrase></code>
object pointed to by <code><phrase role="identifier">f</phrase></code>
and add it to the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is increased by one.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: What does &quot;take ownership&quot; mean here? Does it mean
that fiber_group will eventually delete the fiber*, or does it mean
that *f has become not-a-fiber? Why not <code><phrase role="identifier">add_fiber</phrase><phrase
role="special">(</phrase><phrase role="identifier">fiber</phrase><phrase
role="special">&amp;&amp;</phrase> <phrase role="identifier">f</phrase><phrase
role="special">)</phrase></code>, moving a <code><phrase role="identifier">fiber</phrase></code>
into the group?
</para>
</listitem>
</varlistentry>
</variablelist>
<para>
Oliver: I'm bothered by this scenario:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber_group</phrase> <phrase role="identifier">fg</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase><phrase role="identifier">somefunc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">fg</phrase><phrase role="special">.</phrase><phrase role="identifier">add_fiber</phrase><phrase role="special">(&amp;</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// std::terminate()!
</phrase></programlisting>
<para>
Apparently we would need something more like:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber_group</phrase> <phrase role="identifier">fg</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase><phrase role="identifier">somefunc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">fg</phrase><phrase role="special">.</phrase><phrase role="identifier">add_fiber</phrase><phrase role="special">(&amp;</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="identifier">f</phrase><phrase role="special">.</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase> <phrase role="comment">// okay?
</phrase></programlisting>
<para>
But that doesn't seem very intuitive. I would rather see:
</para>
<programlisting><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber_group</phrase> <phrase role="identifier">fg</phrase><phrase role="special">;</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f</phrase><phrase role="special">(</phrase><phrase role="identifier">somefunc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">fg</phrase><phrase role="special">.</phrase><phrase role="identifier">add_fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">f</phrase><phrase role="special">);</phrase>
<phrase role="comment">// f is now not-a-fiber
</phrase><phrase role="special">}</phrase> <phrase role="comment">// okay
</phrase></programlisting>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__remove_fiber__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__remove_fiber__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">remove_fiber</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">remove_fiber</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="identifier">f</phrase></code> is a member of
the group, remove it without calling <code><phrase role="keyword">delete</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
If <code><phrase role="identifier">f</phrase></code> was a member of
the group, <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">size</phrase><phrase role="special">()</phrase></code>
is decreased by one.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: is this why create_fiber() returns fiber<emphasis role="bold">,
and add_fiber() accepts fiber</emphasis>: so that the caller can retain
a &quot;handle&quot; to a fiber in the group, and possibly later remove
it? It still feels very C++89.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__join_all__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__join_all__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">join_all</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">join_all</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Requires:</term>
<listitem>
<para>
<code><phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">()</phrase>
<phrase role="special">==</phrase> <phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Call <code><phrase role="identifier">join</phrase><phrase role="special">()</phrase></code>
on each <code><phrase role="identifier">fiber</phrase></code> object
in the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
Every fiber in the group has terminated.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Since <code><phrase role="identifier">fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">join</phrase><phrase role="special">()</phrase></code>
is one of the predefined <emphasis>interruption-points</emphasis>,
<code><phrase role="identifier">join_all</phrase><phrase role="special">()</phrase></code>
is also an interruption point.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: What's the distinction between &quot;Requires&quot; and &quot;Precondition&quot;?
What happens if is_this_fiber_in() returns true? Exception? Undefined
behavior?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__is_this_fiber_in__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__is_this_fiber_in__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">is_this_fiber_in</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_this_fiber_in</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
true if there is a fiber <code><phrase role="identifier">f</phrase></code>
in the group such that <code><phrase role="identifier">f</phrase><phrase
role="special">.</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase> <phrase role="special">==</phrase> <phrase
role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__is_fiber_in__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__is_fiber_in__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">is_fiber_in</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">is_fiber_in</phrase><phrase role="special">(</phrase> <phrase role="identifier">fiber</phrase> <phrase role="special">*</phrase> <phrase role="identifier">f</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
true if there is a fiber <code><phrase role="identifier">fx</phrase></code>
in the group such that <code><phrase role="identifier">fx</phrase><phrase
role="special">.</phrase><phrase role="identifier">get_id</phrase><phrase
role="special">()</phrase> <phrase role="special">==</phrase> <phrase
role="identifier">f</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get_id</phrase><phrase role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__interrupt_all__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__interrupt_all__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">interrupt_all</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">interrupt_all</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Call <code><phrase role="identifier">interrupt</phrase><phrase role="special">()</phrase></code>
on each <code><phrase role="identifier">fiber</phrase></code> object
in the group.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__size__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.fiber_group.member_function__code__phrase_role__identifier__size__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">size</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">size</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
The number of fibers in the group.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.fiber_mgmt.attributes">
<title><link linkend="fiber.fiber_mgmt.attributes">Class attributes</link></title>
<para>
Class <code><phrase role="identifier">attributes</phrase></code> is used
to transfer parameters required to set up a fiber's context.
</para>
<important>
<para>
Oliver: definition of flag_unwind_t?
</para>
</important>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">attributes</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">struct</phrase> <phrase role="identifier">attributes</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
<phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">;</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">()</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_unwind</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="keyword">true</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">size_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_unwind</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="keyword">true</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="keyword">true</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_unwind</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">size_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="keyword">true</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size_</phrase><phrase role="special">,</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">size_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_unwind</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase>
<phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">,</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">ctx</phrase><phrase role="special">::</phrase><phrase role="identifier">default_stacksize</phrase><phrase role="special">()</phrase> <phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">attributes</phrase><phrase role="special">(</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">,</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase> <phrase role="identifier">BOOST_NOEXCEPT</phrase> <phrase role="special">:</phrase>
<phrase role="identifier">size</phrase><phrase role="special">(</phrase> <phrase role="identifier">size_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">do_unwind</phrase><phrase role="special">(</phrase> <phrase role="identifier">do_unwind_</phrase><phrase role="special">),</phrase>
<phrase role="identifier">preserve_fpu</phrase><phrase role="special">(</phrase> <phrase role="identifier">preserve_fpu_</phrase><phrase role="special">)</phrase>
<phrase role="special">{}</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.fiber_mgmt.attributes.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.attributes.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">attributes</phrase><phrase role="special">();</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">,</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">);</phrase>
<phrase role="identifier">attributes</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">,</phrase> <phrase role="identifier">flag_unwind_t</phrase> <phrase role="identifier">do_unwind</phrase><phrase role="special">,</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">preserve_fpu</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Parameter <code><phrase role="identifier">size</phrase></code> determines
the stack size; <code><phrase role="identifier">do_unwind</phrase></code>
will controls stack unwinding and <code><phrase role="identifier">preserve_fpu</phrase></code>
preserves FPU registers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: need to say something about the meaning of controlling stack
unwinding, even if the words are merely copied from <emphasis role="bold">Boost.Context</emphasis>.
</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">void</phrase> <phrase role="identifier">yield</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">sleep_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">);</phrase>
<phrase role="keyword">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase> <phrase role="identifier">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>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__get_id__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__get_id__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">get_id</phrase><phrase role="special">()</phrase></code></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">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
An instance of <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">id</phrase></code>
that represents the currently executing fiber.
</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>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__sleep_until__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__sleep_until__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">sleep_until</phrase><phrase role="special">()</phrase></code></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">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">clock_type</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">abs_time</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends the current fiber until the time point specified by <code><phrase
role="identifier">abs_time</phrase></code> has been reached.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code> if
the current fiber is interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">sleep_until</phrase><phrase role="special">()</phrase></code>
is one of the predefined <emphasis>interruption-points</emphasis>.
</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>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__sleep_for__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__sleep_for__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">sleep_for</phrase><phrase role="special">()</phrase></code></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">operations</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">sleep_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">rel_time</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Suspends the current fiber until the time duration specified by <code><phrase
role="identifier">rel_time</phrase></code> has elapsed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing if operations of chrono::duration&lt;Rep, Period&gt; do not
throw exceptions. <code><phrase role="identifier">fiber_interrupted</phrase></code>
if the current fiber is interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">sleep_for</phrase><phrase role="special">()</phrase></code>
is one of the predefined <emphasis>interruption-points</emphasis>.
</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>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__yield__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__yield__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">yield</phrase><phrase role="special">()</phrase></code></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">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> <phrase role="identifier">noexcept</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>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_point__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_point__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">interruption_point</phrase><phrase
role="special">()</phrase></code></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">interruption</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
</programlisting>
<para>
void interruption_point();
</para>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Check to see if the current fiber has been interrupted.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_interrupted</phrase></code> if
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>
and <code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_requested</phrase><phrase role="special">()</phrase></code>
both return <code><phrase role="keyword">true</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_requested__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_requested__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">interruption_requested</phrase><phrase
role="special">()</phrase></code></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">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="identifier">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>
<anchor id="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_enabled__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.non_member_function__code__phrase_role__identifier__interruption_enabled__phrase__phrase_role__special______phrase___code_">Non-member
function <code><phrase role="identifier">interruption_enabled</phrase><phrase
role="special">()</phrase></code></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">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="identifier">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>
<anchor id="fiber.fiber_mgmt.this_fiber.class__code__phrase_role__identifier__disable_interruption__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.class__code__phrase_role__identifier__disable_interruption__phrase___code_">Class
<code><phrase role="identifier">disable_interruption</phrase></code></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">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="identifier">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>
<anchor id="fiber.fiber_mgmt.this_fiber.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">disable_interruption</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Stores the current state of <code><phrase role="identifier">this_fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interruption_enabled</phrase><phrase
role="special">()</phrase></code> and disables interruption for the
current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>
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>
<anchor id="fiber.fiber_mgmt.this_fiber.destructor"/>
<bridgehead renderas="sect4">
<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="identifier">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 <code><phrase role="identifier">this_fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interruption_enabled</phrase><phrase
role="special">()</phrase></code> 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>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>
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>
<anchor id="fiber.fiber_mgmt.this_fiber.class__code__phrase_role__identifier__restore_interruption__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.class__code__phrase_role__identifier__restore_interruption__phrase___code_">Class
<code><phrase role="identifier">restore_interruption</phrase></code></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">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="special">~</phrase><phrase role="identifier">restore_interruption</phrase><phrase role="special">()</phrase> <phrase role="identifier">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>
<important>
<para>
Oliver: would like to see a plausible usage example; I don't yet understand
the purpose of restore_interruption
</para>
</important>
<anchor id="fiber.fiber_mgmt.this_fiber.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.constructor">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="identifier">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 <code><phrase role="identifier">this_fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interruption_enabled</phrase><phrase
role="special">()</phrase></code> for the current fiber to that saved
in <code><phrase role="identifier">disabler</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>
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>
<anchor id="fiber.fiber_mgmt.this_fiber.destructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.fiber_mgmt.this_fiber.destructor">Destructor</link>
</bridgehead>
<programlisting><phrase role="special">~</phrase><phrase role="identifier">restore_interruption</phrase><phrase role="special">()</phrase> <phrase role="identifier">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>
<code><phrase role="identifier">this_fiber</phrase><phrase role="special">::</phrase><phrase
role="identifier">interruption_enabled</phrase><phrase role="special">()</phrase></code>
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>
</section>
</section>
<section id="fiber.stack">
<title><link linkend="fiber.stack">Stack allocation</link></title>
<para>
A <code><phrase role="identifier">fiber</phrase></code> uses internally a
<emphasis>coroutine</emphasis> which manages a set of registers and a stack.
The memory used by the stack is allocated/deallocated via a <emphasis>stack-allocator</emphasis>
which is required to model a <emphasis>stack-allocator concept</emphasis>.
</para>
<anchor id="fiber.stack._emphasis_stack_allocator_concept__emphasis_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack._emphasis_stack_allocator_concept__emphasis_"><emphasis>stack-allocator
concept</emphasis></link>
</bridgehead>
<para>
A <emphasis>stack-allocator</emphasis> must satisfy the <emphasis>stack-allocator
concept</emphasis> requirements shown in the following table, in which <code><phrase
role="identifier">a</phrase></code> is an object of a <emphasis>stack-allocator</emphasis>
type, <code><phrase role="identifier">sctx</phrase></code> is a <code><phrase
role="identifier">stack_context</phrase></code>, and <code><phrase role="identifier">size</phrase></code>
is a <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">size_t</phrase></code>:
</para>
<informaltable frame="all">
<tgroup cols="3">
<thead>
<row>
<entry>
<para>
expression
</para>
</entry>
<entry>
<para>
return type
</para>
</entry>
<entry>
<para>
notes
</para>
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<para>
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
role="identifier">allocate</phrase><phrase role="special">(</phrase>
<phrase role="identifier">sctx</phrase><phrase role="special">,</phrase>
<phrase role="identifier">size</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</entry>
<entry>
<para>
creates a stack of at least <code><phrase role="identifier">size</phrase></code>
bytes and stores both values in <code><phrase role="identifier">sctx</phrase></code>
</para>
</entry>
</row>
<row>
<entry>
<para>
<code><phrase role="identifier">a</phrase><phrase role="special">.</phrase><phrase
role="identifier">deallocate</phrase><phrase role="special">(</phrase>
<phrase role="identifier">sctx</phrase><phrase role="special">)</phrase></code>
</para>
</entry>
<entry>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</entry>
<entry>
<para>
deallocates the stack created by <code><phrase role="identifier">a</phrase><phrase
role="special">.</phrase><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code>
</para>
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<important>
<para>
The implementation of <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> might include logic to protect against
exceeding the context's available stack size rather than leaving it as undefined
behaviour.
</para>
</important>
<important>
<para>
Calling <code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
with a <code><phrase role="identifier">stack_context</phrase></code> not
previously passed to <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> results in undefined behaviour.
</para>
</important>
<note>
<para>
The memory for the stack is not required to be aligned; alignment takes place
inside <emphasis>coroutine</emphasis>.
</para>
</note>
<anchor id="fiber.stack.class__emphasis_stack_allocator__emphasis_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.class__emphasis_stack_allocator__emphasis_">Class
<emphasis>stack_allocator</emphasis></link>
</bridgehead>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides the class <emphasis>coroutine-allocator</emphasis>
which models the <emphasis>stack-allocator concept</emphasis>. It appends a
guard page at the end of each stack to protect against exceeding the stack.
If the guard page is accessed (read or write operation) a segmentation fault/access
violation is generated by the operating system.
</para>
<note>
<para>
The appended <code><phrase role="identifier">guard</phrase> <phrase role="identifier">page</phrase></code>
is <emphasis role="bold">not</emphasis> mapped to physical memory, only virtual
addresses are used.
</para>
</note>
<programlisting><phrase role="preprocessor">#include</phrase> <phrase role="special">&lt;</phrase><phrase role="identifier">boost</phrase><phrase role="special">/</phrase><phrase role="identifier">fiber</phrase><phrase role="special">/</phrase><phrase role="identifier">stack_allocator</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">stack_allocator</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<anchor id="fiber.stack.constructor__code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.constructor__code__phrase_role__keyword__static__phrase___phrase_role__keyword__bool__phrase___phrase_role__identifier__is_stack_unbound__phrase__phrase_role__special______phrase___code_">Constructor
<code><phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase>
<phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">static</phrase> <phrase role="keyword">bool</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the environment
defines no limit for the size of a stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__maximum_stacksize__phrase__phrase_role__special______phrase___code_">Static
member function <code><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the maximum size in bytes of stack defined by the environment.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__default_stacksize__phrase__phrase_role__special______phrase___code_">Static
member function <code><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">default_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">default_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns a default stack size, which may be platform specific. If <code><phrase
role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase></code>
returns <code><phrase role="keyword">true</phrase></code> then the present
implementation returns the maximum of <code><phrase role="number">64</phrase>
<phrase role="identifier">kB</phrase></code> and <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.static_member_function__code__phrase_role__keyword__static__phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__minimum_stacksize__phrase__phrase_role__special______phrase___code_">Static
member function <code><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase
role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase
role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">static</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">minimum_stacksize</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
Returns the minimum size in bytes of stack required by the environment:
Win32 4kB, Win64 8kB, defined by rlimit on POSIX.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.member_function__code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.member_function__code__phrase_role__keyword__void__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">allocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">minimum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&gt;</phrase> <phrase role="identifier">size</phrase></code>
and <code><phrase role="special">!</phrase> <phrase role="identifier">is_stack_unbound</phrase><phrase
role="special">()</phrase> <phrase role="special">&amp;&amp;</phrase>
<phrase role="special">(</phrase> <phrase role="identifier">maximum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&lt;</phrase> <phrase
role="identifier">size</phrase><phrase role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Allocates memory of at least <code><phrase role="identifier">size</phrase></code>
Bytes and stores a pointer to the stack and its actual size in <code><phrase
role="identifier">sctx</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<code><phrase role="keyword">void</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Stores pointer to the start address of the new stack. Depending on the
architecture (stack grows downwards vs. upwards), the stored address
is the highest/lowest address of the stack.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.member_function__code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.member_function__code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">deallocate</phrase><phrase role="special">(</phrase> <phrase role="identifier">stack_context</phrase> <phrase role="special">&amp;);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Preconditions:</term>
<listitem>
<para>
<code><phrase role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">sp</phrase></code> is valid, <code><phrase role="identifier">minimum_stacksize</phrase><phrase
role="special">()</phrase> <phrase role="special">&gt;</phrase> <phrase
role="identifier">sctx</phrase><phrase role="special">.</phrase><phrase
role="identifier">size</phrase></code> and <code><phrase role="special">!</phrase>
<phrase role="identifier">is_stack_unbound</phrase><phrase role="special">()</phrase>
<phrase role="special">&amp;&amp;</phrase> <phrase role="special">(</phrase>
<phrase role="identifier">maximum_stacksize</phrase><phrase role="special">()</phrase>
<phrase role="special">&lt;</phrase> <phrase role="identifier">size</phrase><phrase
role="special">)</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deallocates the stack space.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: wouldn't it be simpler to say something like: <code><phrase role="identifier">sctx</phrase></code>
must have been set by a previous call to <code><phrase role="identifier">allocate</phrase><phrase
role="special">()</phrase></code> since it was most recently passed to
<code><phrase role="identifier">deallocate</phrase><phrase role="special">()</phrase></code>
?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.class__emphasis_stack_context__emphasis_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.class__emphasis_stack_context__emphasis_">Class
<emphasis>stack_context</emphasis></link>
</bridgehead>
<para>
<emphasis role="bold">Boost.Coroutine</emphasis> provides the class <emphasis>stack_context</emphasis>
which will contain the stack pointer and the size of the stack. In case of
a <emphasis>segemented-stack</emphasis>, <emphasis>stack_context</emphasis>
contains some extra control structures.
</para>
<programlisting><phrase role="keyword">struct</phrase> <phrase role="identifier">stack_context</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">void</phrase> <phrase role="special">*</phrase> <phrase role="identifier">sp</phrase><phrase role="special">;</phrase>
<phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">size</phrase><phrase role="special">;</phrase>
<phrase role="comment">// might contain additional control structures,
</phrase> <phrase role="comment">// for instance for segmented stacks
</phrase><phrase role="special">}</phrase>
</programlisting>
<anchor id="fiber.stack.member_variable__code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.member_variable__code__phrase_role__keyword__void__phrase___phrase_role__special_____phrase___phrase_role__identifier__sp__phrase___code_">Member
variable <code><phrase role="keyword">void</phrase> <phrase role="special">*</phrase>
<phrase role="identifier">sp</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Pointer to the beginning of the stack.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Whether the &quot;beginning&quot; of the stack is its lowest address
or its highest address is architecture-dependent.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.member_variable__code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.member_variable__code__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__size__phrase___code_">Member
variable <code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">size_t</phrase> <phrase role="identifier">size</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Value:</term>
<listitem>
<para>
Actual size of the stack, in bytes.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.stack.segmented_stacks"/>
<bridgehead renderas="sect3">
<link linkend="fiber.stack.segmented_stacks">Segmented stacks</link>
</bridgehead>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> supports use of a <emphasis>segemented-stack</emphasis>,
whose size grows on demand. The fiber is created with a minimal stack size,
which will be increased as required.
</para>
<para>
Segmented stacks are currently only supported by <emphasis role="bold">gcc</emphasis>
from version <emphasis role="bold">4.7</emphasis> onwards. In order to use
a <emphasis>segemented-stack</emphasis>, <emphasis role="bold">Boost.Fiber</emphasis>
must be built with <emphasis role="bold">toolset=gcc segmented-stacks=on</emphasis>
at b2/bjam command-line. Applications must be compiled with compiler-flags
<emphasis role="bold">-fsplit-stack -DBOOST_USE_SEGMENTED_STACKS</emphasis>.
</para>
</section>
<section id="fiber.synchronization">
<title><link linkend="fiber.synchronization">Synchronization</link></title>
<section id="fiber.synchronization.mutex_types">
<title><link linkend="fiber.synchronization.mutex_types">Mutex Types</link></title>
<anchor id="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__mutex__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__mutex__phrase___code_">Class
<code><phrase role="identifier">mutex</phrase></code></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">mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">mutex</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<code><phrase role="identifier">mutex</phrase></code> provides an exclusive-ownership
mutex. At most one fiber can own the lock on a given instance of <code><phrase
role="identifier">mutex</phrase></code> 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>
<important>
<para>
Oliver: what do we mean by &quot;multiple concurrent calls&quot; in a fiber
context? I realize you're adapting <emphasis role="bold">Boost.Thread</emphasis>
documentation, but with fibers &quot;concurrent calls&quot; is a peculiar
notion.
</para>
</important>
<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>
<anchor id="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__timed_mutex__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__timed_mutex__phrase___code_">Class
<code><phrase role="identifier">timed_mutex</phrase></code></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">timed_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">timed_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">timed_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">timed_mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<code><phrase role="identifier">timed_mutex</phrase></code> provides an exclusive-ownership
mutex. At most one fiber can own the lock on a given instance of <code><phrase
role="identifier">timed_mutex</phrase></code> 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>
<important>
<para>
Oliver: same remark about &quot;concurrent calls.&quot;
</para>
</important>
<anchor id="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__recursive_mutex__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__recursive_mutex__phrase___code_">Class
<code><phrase role="identifier">recursive_mutex</phrase></code></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">recursive_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">recursive_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">recursive_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">recursive_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">recursive_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">recursive_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">recursive_mutex</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<code><phrase role="identifier">recursive_mutex</phrase></code> provides
an exclusive-ownership recursive mutex. At most one fiber can own the lock
on a given instance of <code><phrase role="identifier">recursive_mutex</phrase></code>
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 <code><phrase role="identifier">recursive_mutex</phrase></code>
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>
<important>
<para>
Oliver: same remark about &quot;concurrent calls.&quot;
</para>
</important>
<anchor id="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__recursive_timed_mutex__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.mutex_types.class__code__phrase_role__identifier__recursive_timed_mutex__phrase___code_">Class
<code><phrase role="identifier">recursive_timed_mutex</phrase></code></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">recursive_timed_mutex</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="special">:</phrase> <phrase role="keyword">private</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">noncopyable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">();</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">(</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">recursive_timed_mutex</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">lock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">unlock</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_lock_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase>
<phrase role="keyword">typedef</phrase> <phrase role="identifier">unique_lock</phrase><phrase role="special">&lt;</phrase><phrase role="identifier">recursive_timed_mutex</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">scoped_lock</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<para>
<code><phrase role="identifier">recursive_timed_mutex</phrase></code> provides
an exclusive-ownership recursive mutex. At most one fiber can own the lock
on a given instance of <code><phrase role="identifier">recursive_timed_mutex</phrase></code>
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 <code><phrase role="identifier">recursive_timed_mutex</phrase></code>
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>
<important>
<para>
Oliver: same remark about &quot;concurrent calls.&quot;
</para>
</important>
</section>
<section id="fiber.synchronization.conditions">
<title><link linkend="fiber.synchronization.conditions">Condition Variables</link></title>
<anchor id="fiber.synchronization.conditions.synopsis"/>
<bridgehead renderas="sect4">
<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="comment">// Oliver: how about a boost::fibers::mutex::scoped_lock?
</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">unique_lock</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="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>
Oliver: is it important to state &quot;atomically&quot; in the paragraph
above?
</para>
<para>
In the meantime, another fiber sets the condition to <code><phrase role="keyword">true</phrase></code>,
and then calls either <code><phrase role="identifier">notify_one</phrase></code>
or <code><phrase role="identifier">notify_all</phrase></code> on the condition
variable to wake one waiting fiber or all the waiting fibers respectively.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">retrieve_data</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">prepare_data</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">prepare_data_for_processing</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">retrieve_data</phrase><phrase role="special">();</phrase>
<phrase role="identifier">prepare_data</phrase><phrase role="special">();</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">lock_guard</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">(</phrase> <phrase role="identifier">mtx</phrase><phrase role="special">);</phrase>
<phrase role="identifier">data_ready</phrase> <phrase role="special">=</phrase> <phrase role="keyword">true</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">cond</phrase><phrase role="special">.</phrase><phrase role="identifier">notify_one</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
Note that the same mutex is locked before the shared data is updated, but
that the mutex does not have to be locked across the call to <code><phrase
role="identifier">notify_one</phrase></code>.
</para>
<anchor id="fiber.synchronization.conditions.class__code__phrase_role__identifier__condition_variable__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.class__code__phrase_role__identifier__condition_variable__phrase___code_">Class
<code><phrase role="identifier">condition_variable</phrase></code></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">condition</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">enum</phrase> <phrase role="identifier">cv_status</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">no_timeout</phrase> <phrase role="special">=</phrase> <phrase role="number">1</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase>
<phrase role="special">};</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">condition_variable</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">condition_variable</phrase><phrase role="special">();</phrase>
<phrase role="special">~</phrase><phrase role="identifier">condition_variable</phrase><phrase role="special">();</phrase>
<phrase role="identifier">condition_variable</phrase><phrase role="special">(</phrase> <phrase role="identifier">condition_variable</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">condition_variable</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">condition_variable</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">notify_one</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">notify_all</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lk</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">predicate</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lt</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lt</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lt</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">lt</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>
<anchor id="fiber.synchronization.conditions.constructor"/>
<bridgehead renderas="sect4">
<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>
<anchor id="fiber.synchronization.conditions.destructor"/>
<bridgehead renderas="sect4">
<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>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: what can we expect if one or more of the fibers waiting on
<code><phrase role="special">*</phrase><phrase role="keyword">this</phrase></code>
have not yet been notified? They go into limbo?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.conditions.member_function__code__phrase_role__identifier__notify_one__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.member_function__code__phrase_role__identifier__notify_one__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">notify_one</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <emphasis>blocked</emphasis> 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>
<anchor id="fiber.synchronization.conditions.member_function__code__phrase_role__identifier__notify_all__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.member_function__code__phrase_role__identifier__notify_all__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">notify_all</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <emphasis>blocked</emphasis> 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>
<anchor id="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_">Templated
member function <code><phrase role="identifier">wait</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">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">lt</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.
Member function using <code><phrase role="identifier">pred</phrase></code>
as-if
<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 <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interrupt</phrase><phrase
role="special">()</phrase></code> on the <code><phrase role="identifier">fiber</phrase></code>
object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: What does the Precondition mean? I can provide an explanation
once I understand it myself, but I do not yet understand it.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_">Templated
member function <code><phrase role="identifier">wait_until</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">LockType</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">cv_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lt</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">LockType</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Pred</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">LockType</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">lt</phrase><phrase role="special">,</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">,</phrase> <phrase role="identifier">Pred</phrase> <phrase role="identifier">pred</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="identifier">lk</phrase></code> is locked by the
current fiber, and either no other fiber is currently waiting on <code><phrase
role="special">*</phrase><phrase role="keyword">this</phrase></code>,
or the execution of the <code><phrase role="identifier">mutex</phrase><phrase
role="special">()</phrase></code> member function on the <code><phrase
role="identifier">lk</phrase></code> objects supplied in the calls
to <code><phrase role="identifier">wait</phrase></code>, <code><phrase
role="identifier">wait_for</phrase></code> or <code><phrase role="identifier">wait_until</phrase></code>
in all the fibers currently waiting on <code><phrase role="special">*</phrase><phrase
role="keyword">this</phrase></code> would return the same value as
<code><phrase role="identifier">lk</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">mutex</phrase><phrase role="special">()</phrase></code>
for this call to <code><phrase role="identifier">wait</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Atomically call <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">unlock</phrase><phrase
role="special">()</phrase></code> and blocks the current fiber. The
fiber will unblock when notified by a call to <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_one</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">notify_all</phrase><phrase
role="special">()</phrase></code>, when the time as reported by <code><phrase
role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase
role="identifier">now</phrase><phrase role="special">()</phrase></code>
would be equal to or later than the specified <code><phrase role="identifier">timeout_time</phrase></code>,
or spuriously. When the fiber is unblocked (for whatever reason), the
lock is reacquired by invoking <code><phrase role="identifier">lk</phrase><phrase
role="special">.</phrase><phrase role="identifier">lock</phrase><phrase
role="special">()</phrase></code> before the call to <code><phrase
role="identifier">wait</phrase></code> returns. The lock is also reacquired
by invoking <code><phrase role="identifier">lk</phrase><phrase role="special">.</phrase><phrase
role="identifier">lock</phrase><phrase role="special">()</phrase></code>
if the function exits with an exception. Member function using <code><phrase
role="identifier">pred</phrase></code> as-if
<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">lt</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>
</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 <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interrupt</phrase><phrase
role="special">()</phrase></code> on the <code><phrase role="identifier">fiber</phrase></code>
object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<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, <code><phrase role="keyword">true</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: but that disagrees with the example above?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.conditions.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_">Templated
member function <code><phrase role="identifier">wait_for</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">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">lt</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">lt</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 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> <phrase
role="special">+</phrase> <phrase role="identifier">timeout_duration</phrase><phrase
role="special">()</phrase></code> would be equal to or later than the
specified time point, 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.
Member function using <code><phrase role="identifier">pred</phrase></code>
as-if
<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">lt</phrase><phrase role="special">,</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase>
<phrase role="keyword">return</phrase> <phrase role="identifier">pred</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">return</phrase> <phrase role="keyword">true</phrase><phrase role="special">;</phrase>
</programlisting>
</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 <code><phrase role="identifier">fiber</phrase><phrase
role="special">::</phrase><phrase role="identifier">interrupt</phrase><phrase
role="special">()</phrase></code> on the <code><phrase role="identifier">fiber</phrase></code>
object associated with the current fiber of execution.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Returns:</term>
<listitem>
<para>
<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, <code><phrase role="keyword">true</phrase></code> otherwise.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: but that disagrees with the example above?
</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>
<anchor id="fiber.synchronization.barriers.class__code__phrase_role__identifier__barrier__phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.barriers.class__code__phrase_role__identifier__barrier__phrase___code_">Class
<code><phrase role="identifier">barrier</phrase></code></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">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 <code><phrase role="identifier">barrier</phrase></code> are
not copyable or movable.
</para>
<anchor id="fiber.synchronization.barriers.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.barriers.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">barrier</phrase><phrase role="special">(</phrase> <phrase role="keyword">unsigned</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">initial</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Construct a barrier for <code><phrase role="identifier">initial</phrase></code>
fibers.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase
role="identifier">invalid_argument</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: under what conditions does the constructor throw? What makes
its argument invalid?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.barriers.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.barriers.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">wait</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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>
Oliver: is this an interruption point?
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.queues">
<title><link linkend="fiber.synchronization.queues">Queues</link></title>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides a bounded and a unbounded
queue suitable to synchonize fibers via message passing.
</para>
<programlisting><phrase role="keyword">typedef</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">unbounded_queue</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">queue_t</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">send</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">for</phrase> <phrase role="special">(</phrase> <phrase role="keyword">int</phrase> <phrase role="identifier">i</phrase> <phrase role="special">=</phrase> <phrase role="number">0</phrase><phrase role="special">;</phrase> <phrase role="identifier">i</phrase> <phrase role="special">&lt;</phrase> <phrase role="number">5</phrase><phrase role="special">;</phrase> <phrase role="special">++</phrase><phrase role="identifier">i</phrase><phrase role="special">)</phrase>
<phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">put</phrase><phrase role="special">(</phrase> <phrase role="identifier">i</phrase><phrase role="special">);</phrase>
<phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">deactivate</phrase><phrase role="special">();</phrase>
<phrase role="special">}</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">recv</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue_t</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">int</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">value</phrase><phrase role="special">;</phrase>
<phrase role="keyword">while</phrase> <phrase role="special">(</phrase> <phrase role="identifier">queue</phrase><phrase role="special">.</phrase><phrase role="identifier">take</phrase><phrase role="special">(</phrase> <phrase role="identifier">value</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="special">*</phrase> <phrase role="identifier">value</phrase> <phrase role="special">&lt;&lt;</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">endl</phrase><phrase role="special">;</phrase> <phrase role="special">}</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">queue_t</phrase> <phrase role="identifier">queue</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f1</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase> <phrase role="identifier">send</phrase><phrase role="special">,</phrase> <phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase> <phrase role="identifier">f2</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">bind</phrase><phrase role="special">(</phrase> <phrase role="identifier">recv</phrase><phrase role="special">,</phrase> <phrase role="identifier">ref</phrase><phrase role="special">(</phrase> <phrase role="identifier">queue</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="special">);</phrase>
<phrase role="identifier">f1</phrase><phrase role="special">.</phrase><phrase role="identifier">join</phrase><phrase role="special">();</phrase>
<phrase role="identifier">f2</phrase><phrase role="special">.</phrase><phrase role="identifier">join</phrase><phrase role="special">();</phrase>
</programlisting>
<anchor id="fiber.synchronization.queues.template__code__phrase_role__identifier__unbounded_queue__phrase__phrase_role__special___lt__gt___phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.template__code__phrase_role__identifier__unbounded_queue__phrase__phrase_role__special___lt__gt___phrase___code_">Template
<code><phrase role="identifier">unbounded_queue</phrase><phrase role="special">&lt;&gt;</phrase></code></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">unbounded_queue</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">unbounded_queue</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">unbounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">unbounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">unbounded_queue</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">unbounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">deactivate</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">put</phrase><phrase role="special">(</phrase> <phrase role="identifier">T</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">t</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__active__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__active__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">active</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Return <code><phrase role="keyword">true</phrase></code> if queue is
still usable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The queue is usable by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__deactivate__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__deactivate__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">deactivate</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">deactivate</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deactivates the queue. No values can be put after calling <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">deactivate</phrase></code>. Fibers blocked in <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">take</phrase><phrase role="special">()</phrase></code>
will return.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">deactivate</phrase><phrase role="special">()</phrase></code>
is like closing a pipe. It informs waiting receivers that no more values
will arrive.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">empty</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the queue
currently contains no data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This condition is transient. An <code><phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code> queue can become non-empty.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__put__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__put__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">put</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">put</phrase><phrase role="special">(</phrase> <phrase role="identifier">T</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">t</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Enqueues the value in the queue and wakes up a fiber waiting for new
data available from the queue.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: this signature appears to impose a requirement that T be copyable.
Would it make sense to support move-only T?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__take__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__take__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">take</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If no data is available from the queue
the fiber gets suspended until at least one new item is enqueued (return
value <code><phrase role="keyword">true</phrase></code> and va contains
dequeued value) or the queue gets deactivated and the function returns
<code><phrase role="keyword">false</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: is this an interruption point?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__try_take__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__try_take__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">try_take</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">try_take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If no data can be retrieved from the
queue at this moment, the function returns <code><phrase role="keyword">false</phrase></code>.
Otherwise it returns <code><phrase role="keyword">true</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains the
dequeued value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
A return value of <code><phrase role="keyword">false</phrase></code>
does not distinguish between <code><phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="special">(!</phrase>
<phrase role="identifier">active</phrase><phrase role="special">())</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.template__code__phrase_role__identifier__bounded_queue__phrase__phrase_role__special___lt__gt___phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.template__code__phrase_role__identifier__bounded_queue__phrase__phrase_role__special___lt__gt___phrase___code_">Template
<code><phrase role="identifier">bounded_queue</phrase><phrase role="special">&lt;&gt;</phrase></code></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">bounded_queue</phrase><phrase role="special">.</phrase><phrase role="identifier">hpp</phrase><phrase role="special">&gt;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">bounded_queue</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">bounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">bounded_queue</phrase> <phrase role="special">&amp;</phrase> <phrase role="keyword">operator</phrase><phrase role="special">=(</phrase> <phrase role="identifier">bounded_queue</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="special">=</phrase> <phrase role="keyword">delete</phrase><phrase role="special">;</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">wm</phrase><phrase role="special">);</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">hwm</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lwm</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">deactivate</phrase><phrase role="special">();</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">put</phrase><phrase role="special">(</phrase> <phrase role="identifier">T</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">t</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="keyword">bool</phrase> <phrase role="identifier">try_take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.queues.constructor"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">wm</phrase><phrase role="special">);</phrase>
<phrase role="identifier">bounded_queue</phrase><phrase role="special">(</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">hwm</phrase><phrase role="special">,</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">lwm</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs an object of class <code><phrase role="identifier">bounded_queue</phrase></code>
which will contain a maximum of <code><phrase role="identifier">wm</phrase></code>
items. The constructor with two arguments constructs an object of class
<code><phrase role="identifier">bounded_queue</phrase></code> which
will contain a high-watermark of <code><phrase role="identifier">hwm</phrase></code>
and a low-watermark of <code><phrase role="identifier">lwm</phrase></code>
items.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__active__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__active__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">active</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">active</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Return <code><phrase role="keyword">true</phrase></code> if queue is
still usable.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The queue is usable by default.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__deactivate__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__deactivate__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">deactivate</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">deactivate</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Deactivates the queue. No values can be put after calling <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">deactivate</phrase></code>. Fibers blocked in <code><phrase
role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">take</phrase><phrase role="special">()</phrase></code>
will return.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
<code><phrase role="identifier">deactivate</phrase><phrase role="special">()</phrase></code>
is like closing a pipe. It informs waiting receivers that no more values
will arrive.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__empty__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">empty</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">empty</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns <code><phrase role="keyword">true</phrase></code> if the queue
currently contains no data.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
This condition is transient. An <code><phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code> queue can become non-empty.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: wouldn't it make sense to have a corresponding <code><phrase
role="identifier">full</phrase><phrase role="special">()</phrase></code>
method?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__put__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__put__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">put</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">put</phrase><phrase role="special">(</phrase> <phrase role="identifier">T</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">t</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Enqueues the value in the queue and wakes up a fiber waiting for new
data available from the queue. When the high water mark is reached,
the fiber putting the value will be supended until at least one item
is dequeued.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: this signature appears to impose a requirement that T be copyable.
Would it make sense to support move-only T?
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: is this an interruption point?
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: wouldn't it make sense to have a corresponding <code><phrase
role="identifier">try_put</phrase><phrase role="special">()</phrase></code>
method?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__take__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__take__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">take</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If no data is available from the queue
the fiber gets suspended until at least one new item is enqueued (return
value <code><phrase role="keyword">true</phrase></code> and va contains
dequeued value) or the queue gets deactivated and the function returns
<code><phrase role="keyword">false</phrase></code>. Once the number
of items remaining in the queue drops below <code><phrase role="identifier">lwm</phrase></code>,
any fibers blocked on <code><phrase role="identifier">put</phrase><phrase
role="special">()</phrase></code> may resume.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
Oliver: is this an interruption point?
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.queues.member_function__code__phrase_role__identifier__try_take__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect4">
<link linkend="fiber.synchronization.queues.member_function__code__phrase_role__identifier__try_take__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">try_take</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">try_take</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">optional</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">T</phrase> <phrase role="special">&gt;</phrase> <phrase role="special">&amp;</phrase> <phrase role="identifier">va</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Dequeues a value from the queue. If no data can be retrieved from the
queue at this moment, the function returns <code><phrase role="keyword">false</phrase></code>.
Otherwise it returns <code><phrase role="keyword">true</phrase></code>
and <code><phrase role="identifier">va</phrase></code> contains the
dequeued value.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
A return value of <code><phrase role="keyword">false</phrase></code>
does not distinguish between <code><phrase role="identifier">empty</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="special">(!</phrase>
<phrase role="identifier">active</phrase><phrase role="special">())</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.futures">
<title><link linkend="fiber.synchronization.futures">Futures</link></title>
<anchor id="fiber.synchronization.futures.overview"/>
<bridgehead renderas="sect4">
<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: <code><phrase
role="identifier">future</phrase></code> and <code><phrase role="identifier">shared_future</phrase></code>
which are used to retrieve the asynchronous results, and <code><phrase role="identifier">promise</phrase></code>
and <code><phrase role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code> which are used to generate the asynchronous
results.
</para>
<para>
An instance of <code><phrase role="identifier">future</phrase></code> 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 <code><phrase role="identifier">future</phrase><phrase
role="special">&lt;&gt;::</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> 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 <code><phrase role="identifier">shared_future</phrase></code>
may reference the same result. Instances can be freely copied and assigned,
and <code><phrase role="identifier">shared_future</phrase><phrase role="special">&lt;&gt;::</phrase><phrase
role="identifier">get</phrase><phrase role="special">()</phrase></code> returns
a non <code><phrase role="keyword">const</phrase></code> reference so that
multiple calls to <code><phrase role="identifier">shared_future</phrase><phrase
role="special">&lt;&gt;::</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> are safe. You can move an instance of
<code><phrase role="identifier">future</phrase></code> into an instance of
<code><phrase role="identifier">shared_future</phrase></code>, 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 <code><phrase role="identifier">future</phrase></code>
that will deliver the result of the task.
</para>
<anchor id="fiber.synchronization.futures.creating_asynchronous_values"/>
<bridgehead renderas="sect4">
<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 <code><phrase role="identifier">promise</phrase></code>
or a <code><phrase role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code>. A <code><phrase role="identifier">packaged</phrase><phrase
role="special">-</phrase><phrase role="identifier">task</phrase></code> 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 <code><phrase role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code> 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 <code><phrase
role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code> and pass the packaged task to the
fiber constructor. The future retrieved from the packaged task can then be
used to obtain the return value. If the function throws an exception, that
is stored in the future in place of the return value.
</para>
<programlisting><phrase role="keyword">int</phrase> <phrase role="identifier">calculate_the_answer_to_life_the_universe_and_everything</phrase><phrase role="special">()</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">return</phrase> <phrase role="number">42</phrase><phrase role="special">;</phrase>
<phrase role="special">}</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">packaged_task</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">pt</phrase><phrase role="special">(</phrase><phrase role="identifier">calculate_the_answer_to_life_the_universe_and_everything</phrase><phrase role="special">);</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase><phrase role="keyword">int</phrase><phrase role="special">&gt;</phrase> <phrase role="identifier">fi</phrase><phrase role="special">=</phrase><phrase role="identifier">pt</phrase><phrase role="special">.</phrase><phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">fiber</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">move</phrase><phrase role="special">(</phrase><phrase role="identifier">pt</phrase><phrase role="special">)).</phrase><phrase role="identifier">detach</phrase><phrase role="special">();</phrase> <phrase role="comment">// launch task on a fiber
</phrase>
<phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">wait</phrase><phrase role="special">();</phrase> <phrase role="comment">// wait for it to finish
</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">is_ready</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_value</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(!</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">has_exception</phrase><phrase role="special">());</phrase>
<phrase role="identifier">assert</phrase><phrase role="special">(</phrase><phrase role="identifier">fi</phrase><phrase role="special">.</phrase><phrase role="identifier">get</phrase><phrase role="special">()==</phrase><phrase role="number">42</phrase><phrase role="special">);</phrase>
</programlisting>
<para>
A <code><phrase role="identifier">promise</phrase></code> 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="fiber.synchronization.futures.future.enumeration__code__phrase_role__identifier__future_status__phrase___code_"/>
<bridgehead renderas="sect5">
<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 (<code><phrase role="identifier">wait_for</phrase><phrase
role="special">()</phrase></code> and <code><phrase role="identifier">wait_until</phrase><phrase
role="special">()</phrase></code>) return the state of the future.
</para>
<programlisting><phrase role="keyword">enum</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">future_status</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">ready</phrase><phrase role="special">,</phrase>
<phrase role="identifier">timeout</phrase><phrase role="special">,</phrase>
<phrase role="identifier">deferred</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.futures.future._code__phrase_role__identifier__ready__phrase___code_"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.future._code__phrase_role__identifier__timeout__phrase___code_"/>
<bridgehead renderas="sect5">
<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 timout has passed.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future._code__phrase_role__identifier__deferred__phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future._code__phrase_role__identifier__deferred__phrase___code_"><code><phrase
role="identifier">deferred</phrase></code></link>
</bridgehead>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
The function is deferred, e.g. result will be computed only when
explictly requested.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.template__code__phrase_role__identifier__future__phrase__phrase_role__special___lt__gt___phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.template__code__phrase_role__identifier__future__phrase__phrase_role__special___lt__gt___phrase___code_">Template
<code><phrase role="identifier">future</phrase><phrase role="special">&lt;&gt;</phrase></code></link>
</bridgehead>
<para>
A <code><phrase role="identifier">future</phrase></code> 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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">shared_future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">share</phrase><phrase role="special">();</phrase>
<phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.futures.future.default_constructor"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.future.move_constructor"/>
<bridgehead renderas="sect5">
<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="identifier">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>
<anchor id="fiber.synchronization.futures.future.destructor"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">=()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">!()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__share__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__share__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">share</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <code><phrase role="identifier">shared_future</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns the result.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">wait</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_">Templated
member function <code><phrase role="identifier">wait_for</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_duration</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">wait_until</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_time</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.template__code__phrase_role__identifier__shared_future__phrase__phrase_role__special___lt__gt___phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.template__code__phrase_role__identifier__shared_future__phrase__phrase_role__special___lt__gt___phrase___code_">Template
<code><phrase role="identifier">shared_future</phrase><phrase role="special">&lt;&gt;</phrase></code></link>
</bridgehead>
<para>
A <code><phrase role="identifier">shared_future</phrase></code> 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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">wait</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.futures.future.default_constructor"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.default_constructor">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>
<anchor id="fiber.synchronization.futures.future.move_constructor"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.move_constructor">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="identifier">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="identifier">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>
<anchor id="fiber.synchronization.futures.future.copy_constructor"/>
<bridgehead renderas="sect5">
<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="identifier">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>
<anchor id="fiber.synchronization.futures.future.destructor"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.destructor">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">=()</phrase></code></link>
</bridgehead>
<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="identifier">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="identifier">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="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">!()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">R</phrase> <phrase role="identifier">get</phrase><phrase role="special">();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Precondition:</term>
<listitem>
<para>
<code><phrase role="keyword">true</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Returns the result.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">false</phrase> <phrase role="special">==</phrase>
<phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">wait</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.templated_member_function__code__phrase_role__identifier__wait_for__phrase__phrase_role__special______phrase___code_">Templated
member function <code><phrase role="identifier">wait_for</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="keyword">class</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_for</phrase><phrase role="special">(</phrase> <phrase role="identifier">chrono</phrase><phrase role="special">::</phrase><phrase role="identifier">duration</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">Rep</phrase><phrase role="special">,</phrase> <phrase role="identifier">Period</phrase> <phrase role="special">&gt;</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_duration</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_duration</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.future.member_function__code__phrase_role__identifier__wait_until__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">wait_until</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="identifier">future_status</phrase> <phrase role="identifier">wait_until</phrase><phrase role="special">(</phrase> <phrase role="identifier">clock_type</phrase><phrase role="special">::</phrase><phrase role="identifier">time_point</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">timeout_time</phrase><phrase role="special">)</phrase> <phrase role="keyword">const</phrase><phrase role="special">;</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Waits for the result will become available or <code><phrase role="identifier">timeout_time</phrase></code>
has passed.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Result:</term>
<listitem>
<para>
A <code><phrase role="identifier">future_status</phrase></code> is
returned indicating the reason for returning.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
error condtion <code><phrase role="identifier">future_errc</phrase><phrase
role="special">::</phrase><phrase role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.synchronization.futures.promise">
<title><link linkend="fiber.synchronization.futures.promise">Template <code><phrase
role="identifier">promise</phrase><phrase role="special">&lt;&gt;</phrase></code></link></title>
<para>
A <code><phrase role="identifier">promise</phrase></code> provides a mechanism
to store a value that can later be accessed asynchronously by a <code><phrase
role="identifier">future</phrase></code> object.
</para>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">promise</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">();</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">promise</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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>
<anchor id="fiber.synchronization.futures.promise.default_constructor"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.promise.constructor"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.constructor">Constructor</link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="identifier">promise</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Creates a promise with an empty shared state by using <code><phrase
role="identifier">alloc</phrase></code>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.promise.move_constructor"/>
<bridgehead renderas="sect5">
<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="identifier">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>
<anchor id="fiber.synchronization.futures.promise.destructor"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">=()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">!()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__get_future__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__get_future__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get_future</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <code><phrase role="identifier">future</phrase></code> 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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__set_value__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__set_value__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">set_value</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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>
<anchor id="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__set_exception__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.promise.member_function__code__phrase_role__identifier__set_exception__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">set_exception</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<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><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 <code><phrase role="identifier">packaged</phrase><phrase role="special">-</phrase><phrase
role="identifier">task</phrase></code> 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">typename</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">class</phrase> <phrase role="identifier">packaged_task</phrase>
<phrase role="special">{</phrase>
<phrase role="keyword">public</phrase><phrase role="special">:</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">()</phrase> <phrase role="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">packaged_task</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">other</phrase><phrase role="special">)</phrase> <phrase role="identifier">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="identifier">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="identifier">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="identifier">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="identifier">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="identifier">noexcept</phrase><phrase role="special">;</phrase>
<phrase role="identifier">future</phrase><phrase role="special">&lt;</phrase> <phrase role="identifier">R</phrase> <phrase role="special">&gt;</phrase> <phrase role="identifier">get_future</phrase><phrase role="special">();</phrase>
<phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
<phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">();</phrase>
<phrase role="special">};</phrase>
</programlisting>
<anchor id="fiber.synchronization.futures.packaged_task.default_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<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>
<anchor 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_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.templated_constructor__code__phrase_role__keyword__template__phrase__phrase_role__special___lt__gt___phrase___phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_">Templated
constructor <code><phrase role="keyword">template</phrase><phrase role="special">&lt;&gt;</phrase>
<phrase role="identifier">packaged_task</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
<phrase role="keyword">template</phrase><phrase role="special">&lt;</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Fn</phrase><phrase role="special">,</phrase> <phrase role="keyword">typename</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="special">&gt;</phrase>
<phrase role="keyword">explicit</phrase> <phrase role="identifier">packaged_task</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">allocator_arg_t</phrase><phrase role="special">,</phrase> <phrase role="identifier">Allocator</phrase> <phrase role="keyword">const</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">alloc</phrase><phrase role="special">,</phrase> <phrase role="identifier">Fn</phrase> <phrase role="special">&amp;&amp;</phrase> <phrase role="identifier">fn</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Constructs an object of class <code><phrase role="identifier">packaged_task</phrase></code>
with a shared state and stores the callable target <code><phrase
role="identifier">fn</phrase></code> internally.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
Nothing.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Note:</term>
<listitem>
<para>
The signature of <code><phrase role="identifier">Fn</phrase></code>
should have a return type convertible to <code><phrase role="identifier">R</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.packaged_task.move_constructor"/>
<bridgehead renderas="sect5">
<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="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.destructor"/>
<bridgehead renderas="sect5">
<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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">=()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__swap__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">swap</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase___phrase_role__identifier__safe_bool__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase
role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">operator</phrase> <phrase role="identifier">safe_bool</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">!()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="keyword">operator</phrase><phrase role="special">!()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__valid__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">valid</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">bool</phrase> <phrase role="identifier">valid</phrase><phrase role="special">()</phrase> <phrase role="keyword">const</phrase> <phrase role="identifier">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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__get_future__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__get_future__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get_future</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <code><phrase role="identifier">future</phrase></code> 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>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special________phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">()()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="keyword">operator</phrase><phrase role="special">()();</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
Invokes the stored callable target. Any exception thrown by the callable
target <code><phrase role="identifier">fn</phrase></code> is stored
in the shared state. Otherwise, the value returned by <code><phrase
role="identifier">fn</phrase></code> is stored in the shared state.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">future_error</phrase></code> with
<code><phrase role="identifier">future_errc</phrase><phrase role="special">::</phrase><phrase
role="identifier">no_state</phrase></code>.
</para>
</listitem>
</varlistentry>
</variablelist>
<anchor id="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__reset__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect5">
<link linkend="fiber.synchronization.futures.packaged_task.member_function__code__phrase_role__identifier__reset__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">reset</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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> <anchor id="fiber.fls.synopsis"/>
<bridgehead renderas="sect3">
<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>
<anchor id="fiber.fls.cleanup_at_fiber_exit"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.cleanup_at_fiber_exit">Cleanup at fiber exit</link>
</bridgehead>
<para>
When a fiber exits, the objects associated with each <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
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. If a cleanup routine sets the value of associated with an instance of
<code><phrase role="identifier">fiber_specific_pointer</phrase></code> that
has already been cleaned up, that value is added to the cleanup list. Cleanup
finishes when there are no outstanding instances of <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
with values.
</para>
<important>
<para>
Oliver: what do the last two sentences above mean?
</para>
</important>
<anchor id="fiber.fls.class_fiber_specific_ptr"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.class_fiber_specific_ptr">Class fiber_specific_ptr</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">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="comment">// Oliver: I'm surprised this doesn't accept a boost::function&lt;void(T*)&gt;.
</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>
<anchor id="fiber.fls.constructor"/>
<bridgehead renderas="sect3">
<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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
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, <code><phrase
role="identifier">fiber_specific_pointer</phrase></code> 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>
<anchor id="fiber.fls.destructor"/>
<bridgehead renderas="sect3">
<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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
(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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
has been destroyed do not call any member functions on that instance.
</para>
</note>
<anchor id="fiber.fls.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.member_function__code__phrase_role__identifier__get__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">get</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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 <code><phrase role="identifier">fiber_specific_pointer</phrase></code>
is <code><phrase role="identifier">NULL</phrase></code> for each fiber.
</para>
</note>
<anchor id="fiber.fls.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special____gt_____phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special____gt_____phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">-&gt;()</phrase></code></link>
</bridgehead>
<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>
<anchor id="fiber.fls.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.member_function__code__phrase_role__keyword__operator__phrase__phrase_role__special_______phrase___code_">Member
function <code><phrase role="keyword">operator</phrase><phrase role="special">*()</phrase></code></link>
</bridgehead>
<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>
<anchor id="fiber.fls.member_function__code__phrase_role__identifier__release__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.member_function__code__phrase_role__identifier__release__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">release</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<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>
<anchor id="fiber.fls.member_function__code__phrase_role__identifier__reset__phrase__phrase_role__special______phrase___code_"/>
<bridgehead renderas="sect3">
<link linkend="fiber.fls.member_function__code__phrase_role__identifier__reset__phrase__phrase_role__special______phrase___code_">Member
function <code><phrase role="identifier">reset</phrase><phrase role="special">()</phrase></code></link>
</bridgehead>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">reset</phrase><phrase role="special">(</phrase><phrase role="identifier">T</phrase><phrase role="special">*</phrase> <phrase role="identifier">new_value</phrase><phrase role="special">=</phrase><phrase role="number">0</phrase><phrase role="special">);</phrase>
</programlisting>
<variablelist>
<title></title>
<varlistentry>
<term>Effects:</term>
<listitem>
<para>
If <code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()!=</phrase><phrase
role="identifier">new_value</phrase></code> and <code><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> is non-<code><phrase role="identifier">NULL</phrase></code>,
invoke <code><phrase role="keyword">delete</phrase> <phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">()</phrase></code> or <code><phrase role="identifier">fn</phrase><phrase
role="special">(</phrase><phrase role="keyword">this</phrase><phrase
role="special">-&gt;</phrase><phrase role="identifier">get</phrase><phrase
role="special">())</phrase></code> as appropriate. Store <code><phrase
role="identifier">new_value</phrase></code> as the pointer associated
with the current fiber.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Postcondition:</term>
<listitem>
<para>
<code><phrase role="keyword">this</phrase><phrase role="special">-&gt;</phrase><phrase
role="identifier">get</phrase><phrase role="special">()==</phrase><phrase
role="identifier">new_value</phrase></code>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Throws:</term>
<listitem>
<para>
<code><phrase role="identifier">fiber_resource_error</phrase></code>
if an error occurs.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="fiber.asio">
<title><link linkend="fiber.asio">Asynchronous network I/O (boost.asio)</link></title>
<para>
In the past, code using asio's <emphasis>asynchronous operations</emphasis>
was scattered by callbacks. <emphasis role="bold">Boost.Asio</emphasis> provides
with its new <emphasis>asynchronous result</emphasis> feature a new way to
simplify the code and make it easier to read. <emphasis>boost::asio::yield_context</emphasis>
internally uses <emphasis role="bold">Boost.Coroutine</emphasis>:
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">echo</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">ip</phrase><phrase role="special">::</phrase><phrase role="identifier">tcp</phrase><phrase role="special">::</phrase><phrase role="identifier">socket</phrase><phrase role="special">&amp;</phrase> <phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">yield_context</phrase> <phrase role="identifier">yield</phrase><phrase role="special">){</phrase>
<phrase role="keyword">char</phrase> <phrase role="identifier">data</phrase><phrase role="special">[</phrase><phrase role="number">128</phrase><phrase role="special">];</phrase>
<phrase role="comment">// read asynchronous data from socket
</phrase> <phrase role="comment">// execution context will be suspended until
</phrase> <phrase role="comment">// some bytes are read from socket
</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">size_t</phrase> <phrase role="identifier">n</phrase><phrase role="special">=</phrase><phrase role="identifier">socket</phrase><phrase role="special">.</phrase><phrase role="identifier">async_read_some</phrase><phrase role="special">(</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="comment">// write some bytes asynchronously
</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_write</phrase><phrase role="special">(</phrase><phrase role="identifier">socket</phrase><phrase role="special">,</phrase><phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase><phrase role="identifier">data</phrase><phrase role="special">,</phrase><phrase role="identifier">n</phrase><phrase role="special">),</phrase><phrase role="identifier">yield</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
</programlisting>
<para>
Unfortunately <emphasis role="bold">Boost.Coroutine</emphasis> (<emphasis>boost::asio::yield_context</emphasis>)
does not provide primitives to synchronize different coroutines (execution
contexts).
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides an integration of <code><phrase
role="identifier">fibers</phrase></code> into <emphasis role="bold">Boost.Asio</emphasis>
so that <emphasis>asynchronous operations</emphasis> from <emphasis role="bold">Boost.Asio</emphasis>
can be used together with fibers, synchronized by primitives provided by <emphasis
role="bold">Boost.Fiber</emphasis>.
</para>
<para>
The example section contains a complete publish-subscribe application demonstrating
the use of fibers with asio's <emphasis>asynchronous operations</emphasis>.
<emphasis>boost::fibers::asio::yield_context</emphasis> abstracts the fiber
in asio's context.
</para>
<programlisting><phrase role="keyword">void</phrase> <phrase role="identifier">subscriber</phrase><phrase role="special">::</phrase><phrase role="identifier">run</phrase><phrase role="special">(</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">yield_fiber</phrase> <phrase role="identifier">yield</phrase><phrase role="special">)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">system</phrase><phrase role="special">::</phrase><phrase role="identifier">error_code</phrase> <phrase role="identifier">ec</phrase><phrase role="special">;</phrase>
<phrase role="comment">// read first message == channel name
</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase> <phrase role="identifier">channel</phrase><phrase role="special">;</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_read</phrase><phrase role="special">(</phrase>
<phrase role="identifier">socket_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase> <phrase role="identifier">channel</phrase><phrase role="special">),</phrase>
<phrase role="identifier">yield</phrase><phrase role="special">[</phrase><phrase role="identifier">ec</phrase><phrase role="special">]);</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">ec</phrase><phrase role="special">)</phrase> <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">&quot;no channel from subscriber&quot;</phrase><phrase role="special">);</phrase>
<phrase role="comment">// register new channel
</phrase> <phrase role="identifier">reg_</phrase><phrase role="special">.</phrase><phrase role="identifier">subscribe</phrase><phrase role="special">(</phrase> <phrase role="identifier">channel</phrase><phrase role="special">,</phrase> <phrase role="identifier">shared_from_this</phrase><phrase role="special">()</phrase> <phrase role="special">);</phrase>
<phrase role="keyword">for</phrase> <phrase role="special">(;;)</phrase>
<phrase role="special">{</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">fibers</phrase><phrase role="special">::</phrase><phrase role="identifier">mutex</phrase><phrase role="special">::</phrase><phrase role="identifier">scoped_lock</phrase> <phrase role="identifier">lk</phrase><phrase role="special">(</phrase> <phrase role="identifier">mtx_</phrase><phrase role="special">);</phrase>
<phrase role="comment">// wait for published messages
</phrase> <phrase role="comment">// fiber gets suspended and will be woken up if a
</phrase> <phrase role="comment">// new message has to be published to subscriber
</phrase> <phrase role="identifier">cond_</phrase><phrase role="special">.</phrase><phrase role="identifier">wait</phrase><phrase role="special">(</phrase> <phrase role="identifier">lk</phrase><phrase role="special">);</phrase>
<phrase role="comment">// '&lt;fini&gt;' terminates subscriber
</phrase> <phrase role="comment">// data_ is a private member of subscriber and
</phrase> <phrase role="comment">// gets filled by the publisher
</phrase> <phrase role="comment">// notification of available data via condition_var cond_
</phrase> <phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="string">&quot;&lt;fini&gt;&quot;</phrase> <phrase role="special">==</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">string</phrase><phrase role="special">(</phrase> <phrase role="identifier">data_</phrase><phrase role="special">)</phrase> <phrase role="special">)</phrase> <phrase role="keyword">break</phrase><phrase role="special">;</phrase>
<phrase role="comment">// write message asynchronously to subscriber
</phrase> <phrase role="comment">// fiber gets suspended until message was written
</phrase> <phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">async_write</phrase><phrase role="special">(</phrase>
<phrase role="identifier">socket_</phrase><phrase role="special">,</phrase>
<phrase role="identifier">boost</phrase><phrase role="special">::</phrase><phrase role="identifier">asio</phrase><phrase role="special">::</phrase><phrase role="identifier">buffer</phrase><phrase role="special">(</phrase> <phrase role="identifier">data_</phrase><phrase role="special">,</phrase> <phrase role="identifier">max_length</phrase><phrase role="special">),</phrase>
<phrase role="identifier">yield</phrase><phrase role="special">[</phrase><phrase role="identifier">ec</phrase><phrase role="special">]);</phrase>
<phrase role="keyword">if</phrase> <phrase role="special">(</phrase> <phrase role="identifier">ec</phrase><phrase role="special">)</phrase> <phrase role="keyword">throw</phrase> <phrase role="identifier">std</phrase><phrase role="special">::</phrase><phrase role="identifier">runtime_error</phrase><phrase role="special">(</phrase><phrase role="string">&quot;publishing message failed&quot;</phrase><phrase role="special">);</phrase>
<phrase role="special">}</phrase>
<phrase role="special">}</phrase>
</programlisting>
<anchor id="fiber.asio.c10k_problem"/>
<bridgehead renderas="sect3">
<link linkend="fiber.asio.c10k_problem">C10K problem</link>
</bridgehead>
<para>
The C10K-website <footnote>
<para>
<ulink url="http://www.kegel.com/c10k.html">'The C10K problem', Dan Kegel</ulink>
</para>
</footnote> from Dan Kegel describes the problem of handling ten thousand clients
simultaneously and which strategies are possible.
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> and <emphasis role="bold">Boost.Asio</emphasis>
support the strategy 'serve many clients with each server thread, and use asynchronous
I/O' without scattering the logic across many callbacks (as was asio's previous
strategy) and overloading the operating system with too many threads. (Beyond
a certain number of threads, the overhead of the kernel scheduler starts to
swamp the available cores.)
</para>
<para>
Because <emphasis role="bold">Boost.Fiber</emphasis> contains synchronization
primitives, it is easy to synchronize different fibers and use asynchronous
network I/O at the same time.
</para>
<para>
<emphasis role="bold">Boost.Fiber</emphasis> provides the same classes and
interfaces as <emphasis role="bold">Boost.Thread</emphasis>. Therefore developers
are able to use patterns familiar from multi-threaded programming. For instance
the strategy 'serve one client with one thread' could be transformed into 'serve
one client with one fiber'.
</para>
</section>
<section id="fiber.acknowledgements">
<title><link linkend="fiber.acknowledgements">Acknowledgments</link></title>
<para>
I'd like to thank Yuriy Krasnoschek and Nat Goodspeed.
</para>
</section>
</library>