]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/fiber/doc/html/fiber/stack/protected_fixedsize/pooled_fixedsize.html
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / fiber / doc / html / fiber / stack / protected_fixedsize / pooled_fixedsize.html
CommitLineData
7c673cae
FG
1<html>
2<head>
3<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
4<title>Class pooled_fixedsize_stack</title>
5<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
6<meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
7<link rel="home" href="../../../index.html" title="Chapter&#160;1.&#160;Fiber">
8<link rel="up" href="../protected_fixedsize.html" title="Class protected_fixedsize_stack">
9<link rel="prev" href="../protected_fixedsize.html" title="Class protected_fixedsize_stack">
10</head>
11<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
12<table cellpadding="2" width="100%"><tr>
13<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
14<td align="center"><a href="../../../../../../../index.html">Home</a></td>
15<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
16<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
17<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
18<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
19</tr></table>
20<hr>
21<div class="spirit-nav">
22<a accesskey="p" href="../protected_fixedsize.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../protected_fixedsize.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
23</div>
24<div class="section">
25<div class="titlepage"><div><div><h4 class="title">
26<a name="fiber.stack.protected_fixedsize.pooled_fixedsize"></a><a class="link" href="pooled_fixedsize.html" title="Class pooled_fixedsize_stack">Class
27 <span class="emphasis"><em>pooled_fixedsize_stack</em></span></a>
28</h4></div></div></div>
29<div class="toc"><dl>
30<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize">Class
31 <span class="emphasis"><em>fixedsize_stack</em></span></a></span></dt>
32<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack">Class
33 <span class="emphasis"><em>segmented_stack</em></span></a></span></dt>
34<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization">Synchronization</a></span></dt>
35<dd><dl>
36<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.mutex_types">Mutex
37 Types</a></span></dt>
38<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions">Condition
39 Variables</a></span></dt>
40<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers">Barriers</a></span></dt>
41<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels">Channels</a></span></dt>
42<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures">Futures</a></span></dt>
43<dd><dl>
44<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future">Future</a></span></dt>
45<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise">Template
46 <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code></a></span></dt>
47<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task">Template
48 <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code></a></span></dt>
49</dl></dd>
50</dl></dd>
51<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls">Fiber
52 local storage</a></span></dt>
53<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration">Migrating
54 fibers between threads</a></span></dt>
55<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks">Integrating
56 Fibers with Asynchronous Callbacks</a></span></dt>
57<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking">Integrating
58 Fibers with Nonblocking I/O</a></span></dt>
59<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any">when_any
60 / when_all functionality</a></span></dt>
61<dd><dl>
62<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any">when_any</a></span></dt>
63<dd><dl>
64<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__simple_completion">when_any,
65 simple completion</a></span></dt>
66<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__return_value">when_any,
67 return value</a></span></dt>
68<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_outcome__whether_result_or_exception">when_any,
69 produce first outcome, whether result or exception</a></span></dt>
70<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_success">when_any,
71 produce first success</a></span></dt>
72<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__heterogeneous_types">when_any,
73 heterogeneous types</a></span></dt>
74<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__a_dubious_alternative">when_any,
75 a dubious alternative</a></span></dt>
76</dl></dd>
77<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality">when_all
78 functionality</a></span></dt>
79<dd><dl>
80<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__simple_completion">when_all,
81 simple completion</a></span></dt>
82<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values">when_all,
83 return values</a></span></dt>
84<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all_until_first_exception">when_all
85 until first exception</a></span></dt>
86<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.wait_all__collecting_all_exceptions">wait_all,
87 collecting all exceptions</a></span></dt>
88<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__heterogeneous_types">when_all,
89 heterogeneous types</a></span></dt>
90</dl></dd>
91</dl></dd>
92<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.integration">Sharing
93 a Thread with Another Main Loop</a></span></dt>
94<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.performance">Performance</a></span></dt>
95<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom">Customization</a></span></dt>
96<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale">Rationale</a></span></dt>
97<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.acknowledgements">Acknowledgments</a></span></dt>
98<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.installing">Appendix:
99 Installing and Running Tests</a></span></dt>
100</dl></div>
101<p>
102 <span class="bold"><strong>Boost.Fiber</strong></span> provides the class <a class="link" href="../../../"> <code class="computeroutput">pooled_fixedsize_stack</code></a> which
103 models the <a class="link" href="../../stack.html#stack_allocator_concept"><span class="emphasis"><em>stack-allocator
104 concept</em></span></a>. In contrast to <a class="link" href="../../../"> <code class="computeroutput">protected_fixedsize_stack</code></a> it
105 does not append a guard page at the end of each stack. The memory is managed
106 internally by <a href="http://www.boost.org/doc/libs/release/libs/pool/doc/html/boost/pool.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">pool</span><span class="special">&lt;&gt;</span></code></a>.
107 </p>
108<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">pooled_fixedsize_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
109
110<span class="keyword">struct</span> <span class="identifier">pooled_fixedsize_stack</span> <span class="special">{</span>
111 <span class="identifier">pooled_fixedsize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stack_size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">next_size</span> <span class="special">=</span> <span class="number">32</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">max_size</span> <span class="special">=</span> <span class="number">0</span><span class="special">);</span>
112
113 <span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
114
115 <span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
116<span class="special">}</span>
117</pre>
118<h6>
119<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.h0"></a>
120 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__identifier__pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__identifier__pooled_fixedsize_stack__phrase__phrase_role__special_____phrase__phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__stack_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__next_size__phrase__phrase_role__special_____phrase___phrase_role__identifier__std__phrase__phrase_role__special______phrase__phrase_role__identifier__size_t__phrase___phrase_role__identifier__max_size__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="identifier">pooled_fixedsize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stack_size</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">next_size</span><span class="special">,</span>
121 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">max_size</span><span class="special">)</span></code></a>
122 </h6>
123<div class="variablelist">
124<p class="title"><b></b></p>
125<dl>
126<dt><span class="term">Preconditions:</span></dt>
127<dd><p>
128 <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
129 <span class="special">||</span> <span class="special">(</span>
130 <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span>
131 <span class="special">&gt;=</span> <span class="identifier">stack_size</span><span class="special">)</span></code> and <code class="computeroutput"><span class="number">0</span>
132 <span class="special">&lt;</span> <span class="identifier">next_size</span></code>.
133 </p></dd>
134<dt><span class="term">Effects:</span></dt>
135<dd><p>
136 Allocates memory of at least <code class="computeroutput"><span class="identifier">stack_size</span></code>
137 bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
138 (the stack grows downwards/upwards) the stored address is the highest/lowest
139 address of the stack. Argument <code class="computeroutput"><span class="identifier">next_size</span></code>
140 determines the number of stacks to request from the system the first
141 time that <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
142 needs to allocate system memory. The third argument <code class="computeroutput"><span class="identifier">max_size</span></code> controls how much memory
143 might be allocated for stacks &#8212; a value of zero means no upper limit.
144 </p></dd>
145</dl>
146</div>
147<h6>
148<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.h1"></a>
149 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
150 </h6>
151<div class="variablelist">
152<p class="title"><b></b></p>
153<dl>
154<dt><span class="term">Preconditions:</span></dt>
155<dd><p>
156 <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span>
157 <span class="special">||</span> <span class="special">(</span>
158 <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span>
159 <span class="special">&gt;=</span> <span class="identifier">stack_size</span><span class="special">)</span></code>.
160 </p></dd>
161<dt><span class="term">Effects:</span></dt>
162<dd><p>
163 Allocates memory of at least <code class="computeroutput"><span class="identifier">stack_size</span></code>
164 bytes and stores a pointer to the stack and its actual size in <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending on the architecture
165 (the stack grows downwards/upwards) the stored address is the highest/lowest
166 address of the stack.
167 </p></dd>
168</dl>
169</div>
170<h6>
171<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.h2"></a>
172 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
173 <span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
174 </h6>
175<div class="variablelist">
176<p class="title"><b></b></p>
177<dl>
178<dt><span class="term">Preconditions:</span></dt>
179<dd><p>
180 <code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">||</span> <span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span> <span class="special">&gt;=</span>
181 <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
182 </p></dd>
183<dt><span class="term">Effects:</span></dt>
184<dd><p>
185 Deallocates the stack space.
186 </p></dd>
187</dl>
188</div>
189<div class="section">
190<div class="titlepage"><div><div><h5 class="title">
191<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize"></a><a name="class_fixedsize_stack"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize" title="Class fixedsize_stack">Class
192 <span class="emphasis"><em>fixedsize_stack</em></span></a>
193</h5></div></div></div>
194<p>
195 <span class="bold"><strong>Boost.Fiber</strong></span> provides the class __fixedsize__
196 which models the <a class="link" href="../../stack.html#stack_allocator_concept"><span class="emphasis"><em>stack-allocator
197 concept</em></span></a>. In contrast to __protected_fixedsize__ it
198 does not append a guard page at the end of each stack. The memory is
199 simply managed by <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">malloc</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">free</span><span class="special">()</span></code>.
200 </p>
201<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">context</span><span class="special">/</span><span class="identifier">fixedsize_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
202
203<span class="keyword">struct</span> <span class="identifier">fixedsize_stack</span> <span class="special">{</span>
204 <span class="identifier">fixedsize_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">());</span>
205
206 <span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
207
208 <span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
209<span class="special">}</span>
210</pre>
211<h6>
212<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize.h0"></a>
213 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
214 </h6>
215<div class="variablelist">
216<p class="title"><b></b></p>
217<dl>
218<dt><span class="term">Preconditions:</span></dt>
219<dd><p>
220 <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum_size</span><span class="special">()</span>
221 <span class="special">&lt;=</span> <span class="identifier">size</span></code>
222 and <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">||</span>
223 <span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span> <span class="special">&gt;=</span>
224 <span class="identifier">size</span><span class="special">)</span></code>.
225 </p></dd>
226<dt><span class="term">Effects:</span></dt>
227<dd><p>
228 Allocates memory of at least <code class="computeroutput"><span class="identifier">size</span></code>
229 bytes and stores a pointer to the stack and its actual size in
230 <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending
231 on the architecture (the stack grows downwards/upwards) the stored
232 address is the highest/lowest address of the stack.
233 </p></dd>
234</dl>
235</div>
236<h6>
237<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize.h1"></a>
238 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fixedsize._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
239 <span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
240 </h6>
241<div class="variablelist">
242<p class="title"><b></b></p>
243<dl>
244<dt><span class="term">Preconditions:</span></dt>
245<dd><p>
246 <code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum_size</span><span class="special">()</span> <span class="special">&lt;=</span>
247 <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span></code> and <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">||</span>
248 <span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span> <span class="special">&gt;=</span>
249 <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
250 </p></dd>
251<dt><span class="term">Effects:</span></dt>
252<dd><p>
253 Deallocates the stack space.
254 </p></dd>
255</dl>
256</div>
257</div>
258<div class="section">
259<div class="titlepage"><div><div><h5 class="title">
260<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack" title="Class segmented_stack">Class
261 <span class="emphasis"><em>segmented_stack</em></span></a>
262</h5></div></div></div>
263<p>
264 <span class="bold"><strong>Boost.Fiber</strong></span> supports usage of a <a class="link" href="../../../"> <code class="computeroutput">segmented_stack</code></a>,
265 i.e. the stack grows on demand. The fiber is created with a minimal stack
266 size which will be increased as required. Class <a class="link" href="../../../"> <code class="computeroutput">segmented_stack</code></a> models
267 the <a class="link" href="../../stack.html#stack_allocator_concept"><span class="emphasis"><em>stack-allocator
268 concept</em></span></a>. In contrast to <a class="link" href="../../../"> <code class="computeroutput">protected_fixedsize_stack</code></a> and
269 <a class="link" href="pooled_fixedsize.html#class_fixedsize_stack"> <code class="computeroutput">fixedsize_stack</code></a> it creates a stack which grows on
270 demand.
271 </p>
272<div class="note"><table border="0" summary="Note">
273<tr>
274<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
275<th align="left">Note</th>
276</tr>
277<tr><td align="left" valign="top"><p>
278 Segmented stacks are currently only supported by <span class="bold"><strong>gcc</strong></span>
279 from version <span class="bold"><strong>4.7</strong></span> and <span class="bold"><strong>clang</strong></span>
280 from version <span class="bold"><strong>3.4</strong></span> onwards. In order
281 to use a <a class="link" href="../../../"> <code class="computeroutput">segmented_stack</code></a> <span class="bold"><strong>Boost.Fiber</strong></span>
282 must be built with property <code class="computeroutput"><span class="identifier">segmented</span><span class="special">-</span><span class="identifier">stacks</span></code>,
283 e.g. <span class="bold"><strong>toolset=gcc segmented-stacks=on</strong></span>
284 at b2/bjam command line.
285 </p></td></tr>
286</table></div>
287<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">segmented_stack</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
288
289<span class="keyword">struct</span> <span class="identifier">segmented_stack</span> <span class="special">{</span>
290 <span class="identifier">segmented_stack</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">stack_size</span> <span class="special">=</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">default_size</span><span class="special">());</span>
291
292 <span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">();</span>
293
294 <span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span> <span class="special">&amp;);</span>
295<span class="special">}</span>
296</pre>
297<h6>
298<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack.h0"></a>
299 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack._code__phrase_role__identifier__stack_context__phrase___phrase_role__identifier__allocate__phrase__phrase_role__special______phrase___code_"><code class="computeroutput"><span class="identifier">stack_context</span> <span class="identifier">allocate</span><span class="special">()</span></code></a>
300 </h6>
301<div class="variablelist">
302<p class="title"><b></b></p>
303<dl>
304<dt><span class="term">Preconditions:</span></dt>
305<dd><p>
306 <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum_size</span><span class="special">()</span>
307 <span class="special">&lt;=</span> <span class="identifier">size</span></code>
308 and <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">||</span>
309 <span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span> <span class="special">&gt;=</span>
310 <span class="identifier">size</span><span class="special">)</span></code>.
311 </p></dd>
312<dt><span class="term">Effects:</span></dt>
313<dd><p>
314 Allocates memory of at least <code class="computeroutput"><span class="identifier">size</span></code>
315 bytes and stores a pointer to the stack and its actual size in
316 <code class="computeroutput"><span class="identifier">sctx</span></code>. Depending
317 on the architecture (the stack grows downwards/upwards) the stored
318 address is the highest/lowest address of the stack.
319 </p></dd>
320</dl>
321</div>
322<h6>
323<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack.h1"></a>
324 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.segmented_stack._code__phrase_role__keyword__void__phrase___phrase_role__identifier__deallocate__phrase__phrase_role__special_____phrase___phrase_role__identifier__stack_context__phrase___phrase_role__special___amp___phrase___phrase_role__identifier__sctx__phrase__phrase_role__special_____phrase___code_"><code class="computeroutput"><span class="keyword">void</span> <span class="identifier">deallocate</span><span class="special">(</span> <span class="identifier">stack_context</span>
325 <span class="special">&amp;</span> <span class="identifier">sctx</span><span class="special">)</span></code></a>
326 </h6>
327<div class="variablelist">
328<p class="title"><b></b></p>
329<dl>
330<dt><span class="term">Preconditions:</span></dt>
331<dd><p>
332 <code class="computeroutput"><span class="identifier">sctx</span><span class="special">.</span><span class="identifier">sp</span></code> is valid, <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">minimum_size</span><span class="special">()</span> <span class="special">&lt;=</span>
333 <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span></code> and <code class="computeroutput"><span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">is_unbounded</span><span class="special">()</span> <span class="special">||</span>
334 <span class="special">(</span> <span class="identifier">traits_type</span><span class="special">::</span><span class="identifier">maximum_size</span><span class="special">()</span> <span class="special">&gt;=</span>
335 <span class="identifier">sctx</span><span class="special">.</span><span class="identifier">size</span><span class="special">)</span></code>.
336 </p></dd>
337<dt><span class="term">Effects:</span></dt>
338<dd><p>
339 Deallocates the stack space.
340 </p></dd>
341</dl>
342</div>
343<div class="note"><table border="0" summary="Note">
344<tr>
345<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
346<th align="left">Note</th>
347</tr>
348<tr><td align="left" valign="top"><p>
349 If the library is compiled for segmented stacks, <a class="link" href="../../../"> <code class="computeroutput">segmented_stack</code></a> is
350 the only available stack allocator.
351 </p></td></tr>
352</table></div>
353</div>
354<div class="section">
355<div class="titlepage"><div><div><h5 class="title">
356<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization"></a><a name="synchronization"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization" title="Synchronization">Synchronization</a>
357</h5></div></div></div>
358<div class="toc"><dl>
359<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.mutex_types">Mutex
360 Types</a></span></dt>
361<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions">Condition
362 Variables</a></span></dt>
363<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers">Barriers</a></span></dt>
364<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels">Channels</a></span></dt>
365<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures">Futures</a></span></dt>
366<dd><dl>
367<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future">Future</a></span></dt>
368<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise">Template
369 <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code></a></span></dt>
370<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task">Template
371 <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code></a></span></dt>
372</dl></dd>
373</dl></div>
374<p>
375 In general, <span class="bold"><strong>Boost.Fiber</strong></span> synchronization
376 objects can neither be moved nor copied. A synchronization object acts
377 as a mutually-agreed rendezvous point between different fibers. If such
378 an object were copied somewhere else, the new copy would have no consumers.
379 If such an object were <span class="emphasis"><em>moved</em></span> somewhere else, leaving
380 the original instance in an unspecified state, existing consumers would
381 behave strangely.
382 </p>
383<p>
384 The fiber synchronization objects provided by this library will, by default,
385 safely synchronize fibers running on different threads. However, this
386 level of synchronization can be removed (for performance) by building
387 the library with <span class="bold"><strong><code class="computeroutput"><span class="identifier">BOOST_FIBERS_NO_ATOMICS</span></code></strong></span>
388 defined. When the library is built with that macro, you must ensure that
389 all the fibers referencing a particular synchronization object are running
390 in the same thread.
391 </p>
392<div class="section">
393<div class="titlepage"><div><div><h6 class="title">
394<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.mutex_types"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.mutex_types" title="Mutex Types">Mutex
395 Types</a>
396</h6></div></div></div>
397<p>
398 </p>
399<h5>
400<a name="class_mutex_bridgehead"></a>
401 <span><a name="class_mutex"></a></span>
402 <a class="link" href="pooled_fixedsize.html#class_mutex">Class <code class="computeroutput">mutex</code></a>
403</h5>
404<p>
405 </p>
406<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
407
408<span class="keyword">class</span> <span class="identifier">mutex</span> <span class="special">{</span>
409<span class="keyword">public</span><span class="special">:</span>
410 <span class="identifier">mutex</span><span class="special">();</span>
411 <span class="special">~</span><span class="identifier">mutex</span><span class="special">();</span>
412
413 <span class="identifier">mutex</span><span class="special">(</span> <span class="identifier">mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
414 <span class="identifier">mutex</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
415
416 <span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
417 <span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">();</span>
418 <span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
419<span class="special">};</span>
420</pre>
421<p>
422 <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a> provides an exclusive-ownership mutex. At most one
423 fiber can own the lock on a given instance of <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a> at any
424 time. Multiple concurrent calls to <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code> shall be permitted.
425 </p>
426<p>
427 Any fiber blocked in <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code> is suspended until the owning fiber
428 releases the lock by calling <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code>.
429 </p>
430<p>
431 </p>
432<h5>
433<a name="mutex_lock_bridgehead"></a>
434 <span><a name="mutex_lock"></a></span>
435 <a class="link" href="pooled_fixedsize.html#mutex_lock">Member function <code class="computeroutput">lock</code>()</a>
436</h5>
437<p>
438 </p>
439<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
440</pre>
441<div class="variablelist">
442<p class="title"><b></b></p>
443<dl>
444<dt><span class="term">Precondition:</span></dt>
445<dd><p>
446 The calling fiber doesn't own the mutex.
447 </p></dd>
448<dt><span class="term">Effects:</span></dt>
449<dd><p>
450 The current fiber blocks until ownership can be obtained.
451 </p></dd>
452<dt><span class="term">Throws:</span></dt>
453<dd><p>
454 <code class="computeroutput"><span class="identifier">lock_error</span></code>
455 </p></dd>
456<dt><span class="term">Error Conditions:</span></dt>
457<dd><p>
458 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
459 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
460 already owns the mutex.
461 </p></dd>
462</dl>
463</div>
464<p>
465 </p>
466<h5>
467<a name="mutex_try_lock_bridgehead"></a>
468 <span><a name="mutex_try_lock"></a></span>
469 <a class="link" href="pooled_fixedsize.html#mutex_try_lock">Member function
470 <code class="computeroutput">try_lock</code>()</a>
471</h5>
472<p>
473 </p>
474<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">();</span>
475</pre>
476<div class="variablelist">
477<p class="title"><b></b></p>
478<dl>
479<dt><span class="term">Precondition:</span></dt>
480<dd><p>
481 The calling fiber doesn't own the mutex.
482 </p></dd>
483<dt><span class="term">Effects:</span></dt>
484<dd><p>
485 Attempt to obtain ownership for the current fiber without blocking.
486 </p></dd>
487<dt><span class="term">Returns:</span></dt>
488<dd><p>
489 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
490 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
491 otherwise.
492 </p></dd>
493<dt><span class="term">Throws:</span></dt>
494<dd><p>
495 <code class="computeroutput"><span class="identifier">lock_error</span></code>
496 </p></dd>
497<dt><span class="term">Error Conditions:</span></dt>
498<dd><p>
499 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
500 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
501 already owns the mutex.
502 </p></dd>
503</dl>
504</div>
505<p>
506 </p>
507<h5>
508<a name="mutex_unlock_bridgehead"></a>
509 <span><a name="mutex_unlock"></a></span>
510 <a class="link" href="pooled_fixedsize.html#mutex_unlock">Member function <code class="computeroutput">unlock</code>()</a>
511</h5>
512<p>
513 </p>
514<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
515</pre>
516<div class="variablelist">
517<p class="title"><b></b></p>
518<dl>
519<dt><span class="term">Precondition:</span></dt>
520<dd><p>
521 The current fiber owns <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
522 </p></dd>
523<dt><span class="term">Effects:</span></dt>
524<dd><p>
525 Releases a lock on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by the current fiber.
526 </p></dd>
527<dt><span class="term">Throws:</span></dt>
528<dd><p>
529 <code class="computeroutput"><span class="identifier">lock_error</span></code>
530 </p></dd>
531<dt><span class="term">Error Conditions:</span></dt>
532<dd><p>
533 <span class="bold"><strong>operation_not_permitted</strong></span>: if
534 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
535 does not own the mutex.
536 </p></dd>
537</dl>
538</div>
539<p>
540 </p>
541<h5>
542<a name="class_timed_mutex_bridgehead"></a>
543 <span><a name="class_timed_mutex"></a></span>
544 <a class="link" href="pooled_fixedsize.html#class_timed_mutex">Class
545 <code class="computeroutput">timed_mutex</code></a>
546</h5>
547<p>
548 </p>
549<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">timed_mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
550
551<span class="keyword">class</span> <span class="identifier">timed_mutex</span> <span class="special">{</span>
552<span class="keyword">public</span><span class="special">:</span>
553 <span class="identifier">timed_mutex</span><span class="special">();</span>
554 <span class="special">~</span><span class="identifier">timed_mutex</span><span class="special">();</span>
555
556 <span class="identifier">timed_mutex</span><span class="special">(</span> <span class="identifier">timed_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
557 <span class="identifier">timed_mutex</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">timed_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
558
559 <span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
560 <span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">();</span>
561 <span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
562
563 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
564 <span class="keyword">bool</span> <span class="identifier">try_lock_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
565 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
566 <span class="keyword">bool</span> <span class="identifier">try_lock_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
567<span class="special">};</span>
568</pre>
569<p>
570 <a class="link" href="pooled_fixedsize.html#class_timed_mutex"> <code class="computeroutput">timed_mutex</code></a> provides an exclusive-ownership mutex.
571 At most one fiber can own the lock on a given instance of <a class="link" href="pooled_fixedsize.html#class_timed_mutex"> <code class="computeroutput">timed_mutex</code></a> at
572 any time. Multiple concurrent calls to <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock_until</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock_for</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code> shall be permitted.
573 </p>
574<p>
575 </p>
576<h5>
577<a name="timed_mutex_lock_bridgehead"></a>
578 <span><a name="timed_mutex_lock"></a></span>
579 <a class="link" href="pooled_fixedsize.html#timed_mutex_lock">Member function
580 <code class="computeroutput">lock</code>()</a>
581</h5>
582<p>
583 </p>
584<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
585</pre>
586<div class="variablelist">
587<p class="title"><b></b></p>
588<dl>
589<dt><span class="term">Precondition:</span></dt>
590<dd><p>
591 The calling fiber doesn't own the mutex.
592 </p></dd>
593<dt><span class="term">Effects:</span></dt>
594<dd><p>
595 The current fiber blocks until ownership can be obtained.
596 </p></dd>
597<dt><span class="term">Throws:</span></dt>
598<dd><p>
599 <code class="computeroutput"><span class="identifier">lock_error</span></code>
600 </p></dd>
601<dt><span class="term">Error Conditions:</span></dt>
602<dd><p>
603 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
604 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
605 already owns the mutex.
606 </p></dd>
607</dl>
608</div>
609<p>
610 </p>
611<h5>
612<a name="timed_mutex_try_lock_bridgehead"></a>
613 <span><a name="timed_mutex_try_lock"></a></span>
614 <a class="link" href="pooled_fixedsize.html#timed_mutex_try_lock">Member
615 function <code class="computeroutput">try_lock</code>()</a>
616</h5>
617<p>
618 </p>
619<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">();</span>
620</pre>
621<div class="variablelist">
622<p class="title"><b></b></p>
623<dl>
624<dt><span class="term">Precondition:</span></dt>
625<dd><p>
626 The calling fiber doesn't own the mutex.
627 </p></dd>
628<dt><span class="term">Effects:</span></dt>
629<dd><p>
630 Attempt to obtain ownership for the current fiber without blocking.
631 </p></dd>
632<dt><span class="term">Returns:</span></dt>
633<dd><p>
634 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
635 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
636 otherwise.
637 </p></dd>
638<dt><span class="term">Throws:</span></dt>
639<dd><p>
640 <code class="computeroutput"><span class="identifier">lock_error</span></code>
641 </p></dd>
642<dt><span class="term">Error Conditions:</span></dt>
643<dd><p>
644 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
645 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
646 already owns the mutex.
647 </p></dd>
648</dl>
649</div>
650<p>
651 </p>
652<h5>
653<a name="timed_mutex_unlock_bridgehead"></a>
654 <span><a name="timed_mutex_unlock"></a></span>
655 <a class="link" href="pooled_fixedsize.html#timed_mutex_unlock">Member
656 function <code class="computeroutput">unlock</code>()</a>
657</h5>
658<p>
659 </p>
660<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
661</pre>
662<div class="variablelist">
663<p class="title"><b></b></p>
664<dl>
665<dt><span class="term">Precondition:</span></dt>
666<dd><p>
667 The current fiber owns <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
668 </p></dd>
669<dt><span class="term">Effects:</span></dt>
670<dd><p>
671 Releases a lock on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by the current fiber.
672 </p></dd>
673<dt><span class="term">Throws:</span></dt>
674<dd><p>
675 <code class="computeroutput"><span class="identifier">lock_error</span></code>
676 </p></dd>
677<dt><span class="term">Error Conditions:</span></dt>
678<dd><p>
679 <span class="bold"><strong>operation_not_permitted</strong></span>: if
680 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
681 does not own the mutex.
682 </p></dd>
683</dl>
684</div>
685<p>
686 </p>
687<h5>
688<a name="timed_mutex_try_lock_until_bridgehead"></a>
689 <span><a name="timed_mutex_try_lock_until"></a></span>
690 <a class="link" href="pooled_fixedsize.html#timed_mutex_try_lock_until">Templated
691 member function <code class="computeroutput">try_lock_until</code>()</a>
692</h5>
693<p>
694 </p>
695<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
696<span class="keyword">bool</span> <span class="identifier">try_lock_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
697</pre>
698<div class="variablelist">
699<p class="title"><b></b></p>
700<dl>
701<dt><span class="term">Precondition:</span></dt>
702<dd><p>
703 The calling fiber doesn't own the mutex.
704 </p></dd>
705<dt><span class="term">Effects:</span></dt>
706<dd><p>
707 Attempt to obtain ownership for the current fiber. Blocks until
708 ownership can be obtained, or the specified time is reached.
709 If the specified time has already passed, behaves as <a class="link" href="pooled_fixedsize.html#timed_mutex_try_lock"> <code class="computeroutput">timed_mutex::try_lock()</code></a>.
710 </p></dd>
711<dt><span class="term">Returns:</span></dt>
712<dd><p>
713 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
714 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
715 otherwise.
716 </p></dd>
717<dt><span class="term">Throws:</span></dt>
718<dd><p>
719 <code class="computeroutput"><span class="identifier">lock_error</span></code>, timeout-related
720 exceptions.
721 </p></dd>
722<dt><span class="term">Error Conditions:</span></dt>
723<dd><p>
724 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
725 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
726 already owns the mutex.
727 </p></dd>
728</dl>
729</div>
730<p>
731 </p>
732<h5>
733<a name="timed_mutex_try_lock_for_bridgehead"></a>
734 <span><a name="timed_mutex_try_lock_for"></a></span>
735 <a class="link" href="pooled_fixedsize.html#timed_mutex_try_lock_for">Templated
736 member function <code class="computeroutput">try_lock_for</code>()</a>
737</h5>
738<p>
739 </p>
740<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
741<span class="keyword">bool</span> <span class="identifier">try_lock_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
742</pre>
743<div class="variablelist">
744<p class="title"><b></b></p>
745<dl>
746<dt><span class="term">Precondition:</span></dt>
747<dd><p>
748 The calling fiber doesn't own the mutex.
749 </p></dd>
750<dt><span class="term">Effects:</span></dt>
751<dd><p>
752 Attempt to obtain ownership for the current fiber. Blocks until
753 ownership can be obtained, or the specified time is reached.
754 If the specified time has already passed, behaves as <a class="link" href="pooled_fixedsize.html#timed_mutex_try_lock"> <code class="computeroutput">timed_mutex::try_lock()</code></a>.
755 </p></dd>
756<dt><span class="term">Returns:</span></dt>
757<dd><p>
758 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
759 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
760 otherwise.
761 </p></dd>
762<dt><span class="term">Throws:</span></dt>
763<dd><p>
764 <code class="computeroutput"><span class="identifier">lock_error</span></code>, timeout-related
765 exceptions.
766 </p></dd>
767<dt><span class="term">Error Conditions:</span></dt>
768<dd><p>
769 <span class="bold"><strong>resource_deadlock_would_occur</strong></span>:
770 if <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
771 already owns the mutex.
772 </p></dd>
773</dl>
774</div>
775<p>
776 </p>
777<h5>
778<a name="class_recursive_mutex_bridgehead"></a>
779 <span><a name="class_recursive_mutex"></a></span>
780 <a class="link" href="pooled_fixedsize.html#class_recursive_mutex">Class
781 <code class="computeroutput">recursive_mutex</code></a>
782</h5>
783<p>
784 </p>
785<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">recursive_mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
786
787<span class="keyword">class</span> <span class="identifier">recursive_mutex</span> <span class="special">{</span>
788<span class="keyword">public</span><span class="special">:</span>
789 <span class="identifier">recursive_mutex</span><span class="special">();</span>
790 <span class="special">~</span><span class="identifier">recursive_mutex</span><span class="special">();</span>
791
792 <span class="identifier">recursive_mutex</span><span class="special">(</span> <span class="identifier">recursive_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
793 <span class="identifier">recursive_mutex</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">recursive_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
794
795 <span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
796 <span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
797 <span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
798<span class="special">};</span>
799</pre>
800<p>
801 <a class="link" href="pooled_fixedsize.html#class_recursive_mutex"> <code class="computeroutput">recursive_mutex</code></a> provides an exclusive-ownership
802 recursive mutex. At most one fiber can own the lock on a given instance
803 of <a class="link" href="pooled_fixedsize.html#class_recursive_mutex"> <code class="computeroutput">recursive_mutex</code></a> at any time. Multiple concurrent
804 calls to <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>,
805 <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code>
806 and <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code>
807 shall be permitted. A fiber that already has exclusive ownership of
808 a given <a class="link" href="pooled_fixedsize.html#class_recursive_mutex"> <code class="computeroutput">recursive_mutex</code></a> instance can call <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>
809 or <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code>
810 to acquire an additional level of ownership of the mutex. <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code>
811 must be called once for each level of ownership acquired by a single
812 fiber before ownership can be acquired by another fiber.
813 </p>
814<p>
815 </p>
816<h5>
817<a name="recursive_mutex_lock_bridgehead"></a>
818 <span><a name="recursive_mutex_lock"></a></span>
819 <a class="link" href="pooled_fixedsize.html#recursive_mutex_lock">Member
820 function <code class="computeroutput">lock</code>()</a>
821</h5>
822<p>
823 </p>
824<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
825</pre>
826<div class="variablelist">
827<p class="title"><b></b></p>
828<dl>
829<dt><span class="term">Effects:</span></dt>
830<dd><p>
831 The current fiber blocks until ownership can be obtained.
832 </p></dd>
833<dt><span class="term">Throws:</span></dt>
834<dd><p>
835 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
836 </p></dd>
837</dl>
838</div>
839<p>
840 </p>
841<h5>
842<a name="recursive_mutex_try_lock_bridgehead"></a>
843 <span><a name="recursive_mutex_try_lock"></a></span>
844 <a class="link" href="pooled_fixedsize.html#recursive_mutex_try_lock">Member
845 function <code class="computeroutput">try_lock</code>()</a>
846</h5>
847<p>
848 </p>
849<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
850</pre>
851<div class="variablelist">
852<p class="title"><b></b></p>
853<dl>
854<dt><span class="term">Effects:</span></dt>
855<dd><p>
856 Attempt to obtain ownership for the current fiber without blocking.
857 </p></dd>
858<dt><span class="term">Returns:</span></dt>
859<dd><p>
860 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
861 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
862 otherwise.
863 </p></dd>
864<dt><span class="term">Throws:</span></dt>
865<dd><p>
866 Nothing.
867 </p></dd>
868</dl>
869</div>
870<p>
871 </p>
872<h5>
873<a name="recursive_mutex_unlock_bridgehead"></a>
874 <span><a name="recursive_mutex_unlock"></a></span>
875 <a class="link" href="pooled_fixedsize.html#recursive_mutex_unlock">Member
876 function <code class="computeroutput">unlock</code>()</a>
877</h5>
878<p>
879 </p>
880<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
881</pre>
882<div class="variablelist">
883<p class="title"><b></b></p>
884<dl>
885<dt><span class="term">Effects:</span></dt>
886<dd><p>
887 Releases a lock on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by the current fiber.
888 </p></dd>
889<dt><span class="term">Throws:</span></dt>
890<dd><p>
891 <code class="computeroutput"><span class="identifier">lock_error</span></code>
892 </p></dd>
893<dt><span class="term">Error Conditions:</span></dt>
894<dd><p>
895 <span class="bold"><strong>operation_not_permitted</strong></span>: if
896 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
897 does not own the mutex.
898 </p></dd>
899</dl>
900</div>
901<p>
902 </p>
903<h5>
904<a name="class_recursive_timed_mutex_bridgehead"></a>
905 <span><a name="class_recursive_timed_mutex"></a></span>
906 <a class="link" href="pooled_fixedsize.html#class_recursive_timed_mutex">Class
907 <code class="computeroutput">recursive_timed_mutex</code></a>
908</h5>
909<p>
910 </p>
911<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">recursive_timed_mutex</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
912
913<span class="keyword">class</span> <span class="identifier">recursive_timed_mutex</span> <span class="special">{</span>
914<span class="keyword">public</span><span class="special">:</span>
915 <span class="identifier">recursive_timed_mutex</span><span class="special">();</span>
916 <span class="special">~</span><span class="identifier">recursive_timed_mutex</span><span class="special">();</span>
917
918 <span class="identifier">recursive_timed_mutex</span><span class="special">(</span> <span class="identifier">recursive_timed_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
919 <span class="identifier">recursive_timed_mutex</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">recursive_timed_mutex</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
920
921 <span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
922 <span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
923 <span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
924
925 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
926 <span class="keyword">bool</span> <span class="identifier">try_lock_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
927 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
928 <span class="keyword">bool</span> <span class="identifier">try_lock_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
929<span class="special">};</span>
930</pre>
931<p>
932 <a class="link" href="pooled_fixedsize.html#class_recursive_timed_mutex"> <code class="computeroutput">recursive_timed_mutex</code></a> provides an exclusive-ownership
933 recursive mutex. At most one fiber can own the lock on a given instance
934 of <a class="link" href="pooled_fixedsize.html#class_recursive_timed_mutex"> <code class="computeroutput">recursive_timed_mutex</code></a> at any time. Multiple
935 concurrent calls to <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock_for</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">try_lock_until</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code> shall be permitted. A fiber that
936 already has exclusive ownership of a given <a class="link" href="pooled_fixedsize.html#class_recursive_timed_mutex"> <code class="computeroutput">recursive_timed_mutex</code></a> instance
937 can call <code class="computeroutput"><span class="identifier">lock</span><span class="special">()</span></code>,
938 <code class="computeroutput"><span class="identifier">try_lock</span><span class="special">()</span></code>,
939 <code class="computeroutput"><span class="identifier">try_lock_for</span><span class="special">()</span></code>
940 or <code class="computeroutput"><span class="identifier">try_lock_until</span><span class="special">()</span></code>
941 to acquire an additional level of ownership of the mutex. <code class="computeroutput"><span class="identifier">unlock</span><span class="special">()</span></code>
942 must be called once for each level of ownership acquired by a single
943 fiber before ownership can be acquired by another fiber.
944 </p>
945<p>
946 </p>
947<h5>
948<a name="recursive_timed_mutex_lock_bridgehead"></a>
949 <span><a name="recursive_timed_mutex_lock"></a></span>
950 <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_lock">Member
951 function <code class="computeroutput">lock</code>()</a>
952</h5>
953<p>
954 </p>
955<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">lock</span><span class="special">();</span>
956</pre>
957<div class="variablelist">
958<p class="title"><b></b></p>
959<dl>
960<dt><span class="term">Effects:</span></dt>
961<dd><p>
962 The current fiber blocks until ownership can be obtained.
963 </p></dd>
964<dt><span class="term">Throws:</span></dt>
965<dd><p>
966 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
967 </p></dd>
968</dl>
969</div>
970<p>
971 </p>
972<h5>
973<a name="recursive_timed_mutex_try_lock_bridgehead"></a>
974 <span><a name="recursive_timed_mutex_try_lock"></a></span>
975 <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_try_lock">Member
976 function <code class="computeroutput">try_lock</code>()</a>
977</h5>
978<p>
979 </p>
980<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">try_lock</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
981</pre>
982<div class="variablelist">
983<p class="title"><b></b></p>
984<dl>
985<dt><span class="term">Effects:</span></dt>
986<dd><p>
987 Attempt to obtain ownership for the current fiber without blocking.
988 </p></dd>
989<dt><span class="term">Returns:</span></dt>
990<dd><p>
991 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
992 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
993 otherwise.
994 </p></dd>
995<dt><span class="term">Throws:</span></dt>
996<dd><p>
997 Nothing.
998 </p></dd>
999</dl>
1000</div>
1001<p>
1002 </p>
1003<h5>
1004<a name="recursive_timed_mutex_unlock_bridgehead"></a>
1005 <span><a name="recursive_timed_mutex_unlock"></a></span>
1006 <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_unlock">Member
1007 function <code class="computeroutput">unlock</code>()</a>
1008</h5>
1009<p>
1010 </p>
1011<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">unlock</span><span class="special">();</span>
1012</pre>
1013<div class="variablelist">
1014<p class="title"><b></b></p>
1015<dl>
1016<dt><span class="term">Effects:</span></dt>
1017<dd><p>
1018 Releases a lock on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> by the current fiber.
1019 </p></dd>
1020<dt><span class="term">Throws:</span></dt>
1021<dd><p>
1022 <code class="computeroutput"><span class="identifier">lock_error</span></code>
1023 </p></dd>
1024<dt><span class="term">Error Conditions:</span></dt>
1025<dd><p>
1026 <span class="bold"><strong>operation_not_permitted</strong></span>: if
1027 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span></code>
1028 does not own the mutex.
1029 </p></dd>
1030</dl>
1031</div>
1032<p>
1033 </p>
1034<h5>
1035<a name="recursive_timed_mutex_try_lock_until_bridgehead"></a>
1036 <span><a name="recursive_timed_mutex_try_lock_until"></a></span>
1037 <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_try_lock_until">Templated
1038 member function <code class="computeroutput">try_lock_until</code>()</a>
1039</h5>
1040<p>
1041 </p>
1042<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
1043<span class="keyword">bool</span> <span class="identifier">try_lock_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
1044</pre>
1045<div class="variablelist">
1046<p class="title"><b></b></p>
1047<dl>
1048<dt><span class="term">Effects:</span></dt>
1049<dd><p>
1050 Attempt to obtain ownership for the current fiber. Blocks until
1051 ownership can be obtained, or the specified time is reached.
1052 If the specified time has already passed, behaves as <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_try_lock"> <code class="computeroutput">recursive_timed_mutex::try_lock()</code></a>.
1053 </p></dd>
1054<dt><span class="term">Returns:</span></dt>
1055<dd><p>
1056 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
1057 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
1058 otherwise.
1059 </p></dd>
1060<dt><span class="term">Throws:</span></dt>
1061<dd><p>
1062 Timeout-related exceptions.
1063 </p></dd>
1064</dl>
1065</div>
1066<p>
1067 </p>
1068<h5>
1069<a name="recursive_timed_mutex_try_lock_for_bridgehead"></a>
1070 <span><a name="recursive_timed_mutex_try_lock_for"></a></span>
1071 <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_try_lock_for">Templated
1072 member function <code class="computeroutput">try_lock_for</code>()</a>
1073</h5>
1074<p>
1075 </p>
1076<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
1077<span class="keyword">bool</span> <span class="identifier">try_lock_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
1078</pre>
1079<div class="variablelist">
1080<p class="title"><b></b></p>
1081<dl>
1082<dt><span class="term">Effects:</span></dt>
1083<dd><p>
1084 Attempt to obtain ownership for the current fiber. Blocks until
1085 ownership can be obtained, or the specified time is reached.
1086 If the specified time has already passed, behaves as <a class="link" href="pooled_fixedsize.html#recursive_timed_mutex_try_lock"> <code class="computeroutput">recursive_timed_mutex::try_lock()</code></a>.
1087 </p></dd>
1088<dt><span class="term">Returns:</span></dt>
1089<dd><p>
1090 <code class="computeroutput"><span class="keyword">true</span></code> if ownership
1091 was obtained for the current fiber, <code class="computeroutput"><span class="keyword">false</span></code>
1092 otherwise.
1093 </p></dd>
1094<dt><span class="term">Throws:</span></dt>
1095<dd><p>
1096 Timeout-related exceptions.
1097 </p></dd>
1098</dl>
1099</div>
1100</div>
1101<div class="section">
1102<div class="titlepage"><div><div><h6 class="title">
1103<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions" title="Condition Variables">Condition
1104 Variables</a>
1105</h6></div></div></div>
1106<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h0"></a>
1107 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.synopsis"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.synopsis">Synopsis</a>
1108 </h7><pre class="programlisting"><span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">cv_status</span><span class="special">;</span> <span class="special">{</span>
1109 <span class="identifier">no_timeout</span><span class="special">,</span>
1110 <span class="identifier">timeout</span>
1111<span class="special">};</span>
1112
1113<span class="keyword">class</span> <span class="identifier">condition_variable</span><span class="special">;</span>
1114<span class="keyword">class</span> <span class="identifier">condition_variable_any</span><span class="special">;</span>
1115</pre>
1116<p>
1117 The class <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> provides a mechanism
1118 for a fiber to wait for notification from another fiber. When the fiber
1119 awakens from the wait, then it checks to see if the appropriate condition
1120 is now true, and continues if so. If the condition is not true, then
1121 the fiber calls <code class="computeroutput"><span class="identifier">wait</span></code>
1122 again to resume waiting. In the simplest case, this condition is just
1123 a boolean variable:
1124 </p>
1125<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">cond</span><span class="special">;</span>
1126<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mtx</span><span class="special">;</span>
1127<span class="keyword">bool</span> <span class="identifier">data_ready</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
1128
1129<span class="keyword">void</span> <span class="identifier">process_data</span><span class="special">();</span>
1130
1131<span class="keyword">void</span> <span class="identifier">wait_for_data_to_process</span><span class="special">()</span> <span class="special">{</span>
1132 <span class="special">{</span>
1133 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx</span><span class="special">);</span>
1134 <span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">data_ready</span><span class="special">)</span> <span class="special">{</span>
1135 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">);</span>
1136 <span class="special">}</span>
1137 <span class="special">}</span> <span class="comment">// release lk</span>
1138 <span class="identifier">process_data</span><span class="special">();</span>
1139<span class="special">}</span>
1140</pre>
1141<p>
1142 Notice that the <code class="computeroutput"><span class="identifier">lk</span></code>
1143 is passed to <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a>: <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
1144 will atomically add the fiber to the set of fibers waiting on the condition
1145 variable, and unlock the <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a>. When the fiber is awakened,
1146 the <code class="computeroutput"><span class="identifier">mutex</span></code> will be locked
1147 again before the call to <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code> returns. This allows other fibers
1148 to acquire the <code class="computeroutput"><span class="identifier">mutex</span></code>
1149 in order to update the shared data, and ensures that the data associated
1150 with the condition is correctly synchronized.
1151 </p>
1152<p>
1153 <code class="computeroutput"><span class="identifier">wait_for_data_to_process</span><span class="special">()</span></code> could equivalently be written:
1154 </p>
1155<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">wait_for_data_to_process</span><span class="special">()</span> <span class="special">{</span>
1156 <span class="special">{</span>
1157 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx</span><span class="special">);</span>
1158 <span class="comment">// make condition_variable::wait() perform the loop</span>
1159 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">data_ready</span><span class="special">;</span> <span class="special">});</span>
1160 <span class="special">}</span> <span class="comment">// release lk</span>
1161 <span class="identifier">process_data</span><span class="special">();</span>
1162<span class="special">}</span>
1163</pre>
1164<p>
1165 In the meantime, another fiber sets <code class="computeroutput"><span class="identifier">data_ready</span></code>
1166 to <code class="computeroutput"><span class="keyword">true</span></code>, and then calls
1167 either <a class="link" href="pooled_fixedsize.html#condition_variable_notify_one"> <code class="computeroutput">condition_variable::notify_one()</code></a> or
1168 <a class="link" href="pooled_fixedsize.html#condition_variable_notify_all"> <code class="computeroutput">condition_variable::notify_all()</code></a> on the
1169 <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> <code class="computeroutput"><span class="identifier">cond</span></code>
1170 to wake one waiting fiber or all the waiting fibers respectively.
1171 </p>
1172<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">retrieve_data</span><span class="special">();</span>
1173<span class="keyword">void</span> <span class="identifier">prepare_data</span><span class="special">();</span>
1174
1175<span class="keyword">void</span> <span class="identifier">prepare_data_for_processing</span><span class="special">()</span> <span class="special">{</span>
1176 <span class="identifier">retrieve_data</span><span class="special">();</span>
1177 <span class="identifier">prepare_data</span><span class="special">();</span>
1178 <span class="special">{</span>
1179 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx</span><span class="special">);</span>
1180 <span class="identifier">data_ready</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
1181 <span class="special">}</span>
1182 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">notify_one</span><span class="special">();</span>
1183<span class="special">}</span>
1184</pre>
1185<p>
1186 Note that the same <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a> is locked before the shared data
1187 is updated, but that the <code class="computeroutput"><span class="identifier">mutex</span></code>
1188 does not have to be locked across the call to <a class="link" href="pooled_fixedsize.html#condition_variable_notify_one"> <code class="computeroutput">condition_variable::notify_one()</code></a>.
1189 </p>
1190<p>
1191 Locking is important because the synchronization objects provided by
1192 <span class="bold"><strong>Boost.Fiber</strong></span> can be used to synchronize
1193 fibers running on different threads.
1194 </p>
1195<p>
1196 <span class="bold"><strong>Boost.Fiber</strong></span> provides both <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> and
1197 <a class="link" href="pooled_fixedsize.html#class_condition_variable_any"> <code class="computeroutput">condition_variable_any</code></a>. <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">condition_variable</span></code>
1198 can only wait on <a href="http://en.cppreference.com/w/cpp/thread/unique_lock" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span></code></a><code class="computeroutput"><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span></code> <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a><code class="computeroutput"> <span class="special">&gt;</span></code>
1199 while <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">condition_variable_any</span></code> can wait on
1200 user-defined lock types.
1201 </p>
1202<a name="condition_variable_spurious_wakeups"></a><h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h1"></a>
1203 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.no_spurious_wakeups"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.no_spurious_wakeups">No
1204 Spurious Wakeups</a>
1205 </h7><p>
1206 Neither <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> nor <a class="link" href="pooled_fixedsize.html#class_condition_variable_any"> <code class="computeroutput">condition_variable_any</code></a> are
1207 subject to spurious wakeup: <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a> can
1208 only wake up when <a class="link" href="pooled_fixedsize.html#condition_variable_notify_one"> <code class="computeroutput">condition_variable::notify_one()</code></a> or
1209 <a class="link" href="pooled_fixedsize.html#condition_variable_notify_all"> <code class="computeroutput">condition_variable::notify_all()</code></a> is called.
1210 Even so, it is prudent to use one of the <code class="computeroutput"><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lock</span><span class="special">,</span> <span class="identifier">predicate</span>
1211 <span class="special">)</span></code> overloads.
1212 </p>
1213<p>
1214 Consider a set of consumer fibers processing items from a <a href="http://en.cppreference.com/w/cpp/container/queue" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">queue</span></code></a>. The queue is continually
1215 populated by a set of producer fibers.
1216 </p>
1217<p>
1218 The consumer fibers might reasonably wait on a <code class="computeroutput"><span class="identifier">condition_variable</span></code>
1219 as long as the queue remains <a href="http://en.cppreference.com/w/cpp/container/queue/empty" target="_top"><code class="computeroutput"><span class="identifier">empty</span><span class="special">()</span></code></a>.
1220 </p>
1221<p>
1222 Because producer fibers might <a href="http://en.cppreference.com/w/cpp/container/queue/push" target="_top"><code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code></a>
1223 items to the queue in bursts, they call <a class="link" href="pooled_fixedsize.html#condition_variable_notify_all"> <code class="computeroutput">condition_variable::notify_all()</code></a> rather
1224 than <a class="link" href="pooled_fixedsize.html#condition_variable_notify_one"> <code class="computeroutput">condition_variable::notify_one()</code></a>.
1225 </p>
1226<p>
1227 But a given consumer fiber might well wake up from <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a> and
1228 find the queue <code class="computeroutput"><span class="identifier">empty</span><span class="special">()</span></code>, because other consumer fibers might
1229 already have processed all pending items.
1230 </p>
1231<p>
1232 (See also <a class="link" href="pooled_fixedsize.html#spurious_wakeup">spurious wakeup</a>.)
1233 </p>
1234<a name="class_cv_status"></a><h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h2"></a>
1235 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.enumeration__code__phrase_role__identifier__cv_status__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.enumeration__code__phrase_role__identifier__cv_status__phrase___code_">Enumeration
1236 <code class="computeroutput"><span class="identifier">cv_status</span></code></a>
1237 </h7><p>
1238 A timed wait operation might return because of timeout or not.
1239 </p>
1240<pre class="programlisting"><span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">cv_status</span> <span class="special">{</span>
1241 <span class="identifier">no_timeout</span><span class="special">,</span>
1242 <span class="identifier">timeout</span>
1243<span class="special">};</span>
1244</pre>
1245<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h3"></a>
1246 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions._code__phrase_role__identifier__no_timeout__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions._code__phrase_role__identifier__no_timeout__phrase___code_"><code class="computeroutput"><span class="identifier">no_timeout</span></code></a>
1247 </h7><div class="variablelist">
1248<p class="title"><b></b></p>
1249<dl>
1250<dt><span class="term">Effects:</span></dt>
1251<dd><p>
1252 The condition variable was awakened with <code class="computeroutput"><span class="identifier">notify_one</span></code>
1253 or <code class="computeroutput"><span class="identifier">notify_all</span></code>.
1254 </p></dd>
1255</dl>
1256</div>
1257<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h4"></a>
1258 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions._code__phrase_role__identifier__timeout__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions._code__phrase_role__identifier__timeout__phrase___code_"><code class="computeroutput"><span class="identifier">timeout</span></code></a>
1259 </h7><div class="variablelist">
1260<p class="title"><b></b></p>
1261<dl>
1262<dt><span class="term">Effects:</span></dt>
1263<dd><p>
1264 The condition variable was awakened by timeout.
1265 </p></dd>
1266</dl>
1267</div>
1268<p>
1269 </p>
1270<h5>
1271<a name="class_condition_variable_any_bridgehead"></a>
1272 <span><a name="class_condition_variable_any"></a></span>
1273 <a class="link" href="pooled_fixedsize.html#class_condition_variable_any">Class
1274 <code class="computeroutput">condition_variable_any</code></a>
1275</h5>
1276<p>
1277 </p>
1278<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">condition_variable</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1279
1280<span class="keyword">class</span> condition_variable_any <span class="special">{</span>
1281<span class="keyword">public</span><span class="special">:</span>
1282 condition_variable_any<span class="special">();</span>
1283 <span class="special">~</span>condition_variable_any<span class="special">();</span>
1284
1285 condition_variable_any<span class="special">(</span> condition_variable_any <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
1286 condition_variable_any <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> condition_variable_any <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
1287
1288 <span class="keyword">void</span> <span class="identifier">notify_one</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1289 <span class="keyword">void</span> <span class="identifier">notify_all</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1290
1291 template&lt; typename LockType &gt;
1292 void <span class="identifier">wait</span><span class="special">(</span> LockType <span class="special">&amp;);</span>
1293
1294 <span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Pred</span> <span class="special">&gt;</span>
1295 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">(</span> LockType <span class="special">&amp;,</span> <span class="identifier">Pred</span><span class="special">);</span>
1296
1297 <span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
1298 <span class="identifier">cv_status</span> <span class="identifier">wait_until</span><span class="special">(</span> LockType <span class="special">&amp;,</span>
1299 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;);</span>
1300
1301 <span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1302 <span class="keyword">bool</span> <span class="identifier">wait_until</span><span class="special">(</span> LockType <span class="special">&amp;,</span>
1303 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;,</span>
1304 <span class="identifier">Pred</span><span class="special">);</span>
1305
1306 <span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
1307 <span class="identifier">cv_status</span> <span class="identifier">wait_for</span><span class="special">(</span> LockType <span class="special">&amp;,</span>
1308 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;);</span>
1309
1310 <span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1311 <span class="keyword">bool</span> <span class="identifier">wait_for</span><span class="special">(</span> LockType <span class="special">&amp;,</span>
1312 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;,</span>
1313 <span class="identifier">Pred</span><span class="special">);</span>
1314<span class="special">};</span>
1315</pre>
1316<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h5"></a>
1317 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.constructor">Constructor</a>
1318 </h7><pre class="programlisting">condition_variable_any<span class="special">()</span>
1319</pre>
1320<div class="variablelist">
1321<p class="title"><b></b></p>
1322<dl>
1323<dt><span class="term">Effects:</span></dt>
1324<dd><p>
1325 Creates the object.
1326 </p></dd>
1327<dt><span class="term">Throws:</span></dt>
1328<dd><p>
1329 Nothing.
1330 </p></dd>
1331</dl>
1332</div>
1333<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h6"></a>
1334 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.destructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.destructor">Destructor</a>
1335 </h7><pre class="programlisting"><span class="special">~</span>condition_variable_any<span class="special">()</span>
1336</pre>
1337<div class="variablelist">
1338<p class="title"><b></b></p>
1339<dl>
1340<dt><span class="term">Precondition:</span></dt>
1341<dd><p>
1342 All fibers waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> have been notified by a call
1343 to <code class="computeroutput"><span class="identifier">notify_one</span></code>
1344 or <code class="computeroutput"><span class="identifier">notify_all</span></code>
1345 (though the respective calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
1346 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1347 <code class="computeroutput"><span class="identifier">wait_until</span></code> need
1348 not have returned).
1349 </p></dd>
1350<dt><span class="term">Effects:</span></dt>
1351<dd><p>
1352 Destroys the object.
1353 </p></dd>
1354</dl>
1355</div>
1356<p>
1357 </p>
1358<h5>
1359<a name="condition_variable_any_notify_one_bridgehead"></a>
1360 <span><a name="condition_variable_any_notify_one"></a></span>
1361 <a class="link" href="pooled_fixedsize.html#condition_variable_any_notify_one">Member
1362 function <code class="computeroutput">notify_one</code>()</a>
1363</h5>
1364<p>
1365 </p>
1366<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">notify_one</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1367</pre>
1368<div class="variablelist">
1369<p class="title"><b></b></p>
1370<dl>
1371<dt><span class="term">Effects:</span></dt>
1372<dd><p>
1373 If any fibers are currently <a class="link" href="../../overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>
1374 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1375 in a call to <code class="computeroutput"><span class="identifier">wait</span></code>,
1376 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1377 <code class="computeroutput"><span class="identifier">wait_until</span></code>, unblocks
1378 one of those fibers.
1379 </p></dd>
1380<dt><span class="term">Throws:</span></dt>
1381<dd><p>
1382 Nothing.
1383 </p></dd>
1384<dt><span class="term">Note:</span></dt>
1385<dd><p>
1386 It is arbitrary which waiting fiber is resumed.
1387 </p></dd>
1388</dl>
1389</div>
1390<p>
1391 </p>
1392<h5>
1393<a name="condition_variable_any_notify_all_bridgehead"></a>
1394 <span><a name="condition_variable_any_notify_all"></a></span>
1395 <a class="link" href="pooled_fixedsize.html#condition_variable_any_notify_all">Member
1396 function <code class="computeroutput">notify_all</code>()</a>
1397</h5>
1398<p>
1399 </p>
1400<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">notify_all</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1401</pre>
1402<div class="variablelist">
1403<p class="title"><b></b></p>
1404<dl>
1405<dt><span class="term">Effects:</span></dt>
1406<dd><p>
1407 If any fibers are currently <a class="link" href="../../overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>
1408 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1409 in a call to <code class="computeroutput"><span class="identifier">wait</span></code>,
1410 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1411 <code class="computeroutput"><span class="identifier">wait_until</span></code>, unblocks
1412 all of those fibers.
1413 </p></dd>
1414<dt><span class="term">Throws:</span></dt>
1415<dd><p>
1416 Nothing.
1417 </p></dd>
1418<dt><span class="term">Note:</span></dt>
1419<dd><p>
1420 This is why a waiting fiber must <span class="emphasis"><em>also</em></span> check
1421 for the desired program state using a mechanism external to the
1422 <code class="computeroutput">condition_variable_any</code>, and retry the wait until that state is
1423 reached. A fiber waiting on a <code class="computeroutput">condition_variable_any</code> might well
1424 wake up a number of times before the desired state is reached.
1425 </p></dd>
1426</dl>
1427</div>
1428<p>
1429 </p>
1430<h5>
1431<a name="condition_variable_any_wait_bridgehead"></a>
1432 <span><a name="condition_variable_any_wait"></a></span>
1433 <a class="link" href="pooled_fixedsize.html#condition_variable_any_wait">Templated
1434 member function <code class="computeroutput">wait</code>()</a>
1435</h5>
1436<p>
1437 </p>
1438<pre class="programlisting">template&lt; typename LockType &gt;
1439 void <span class="identifier">wait</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">);</span>
1440
1441<span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Pred</span> <span class="special">&gt;</span>
1442<span class="keyword">void</span> <span class="identifier">wait</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
1443</pre>
1444<div class="variablelist">
1445<p class="title"><b></b></p>
1446<dl>
1447<dt><span class="term">Precondition:</span></dt>
1448<dd><p>
1449 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1450 by the current fiber, and either no other fiber is currently
1451 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
1452 or the execution of the <a href="http://en.cppreference.com/w/cpp/thread/unique_lock/mutex" target="_top"><code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code></a>
1453 member function on the <code class="computeroutput"><span class="identifier">lk</span></code>
1454 objects supplied in the calls to <code class="computeroutput"><span class="identifier">wait</span></code>
1455 in all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
1456 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">-&gt;</span><span class="identifier">mutex</span><span class="special">()</span></code>
1457 for this call to <code class="computeroutput"><span class="identifier">wait</span></code>.
1458 </p></dd>
1459<dt><span class="term">Effects:</span></dt>
1460<dd>
1461<p>
1462 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
1463 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
1464 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>.
1465 When the fiber is unblocked (for whatever reason), the lock is
1466 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait</span></code> returns. The lock is also
1467 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
1468 an exception. The member function accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1469 is shorthand for:
1470</p>
1471<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
1472 <span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">);</span>
1473<span class="special">}</span>
1474</pre>
1475<p>
1476 </p>
1477</dd>
1478<dt><span class="term">Postcondition:</span></dt>
1479<dd><p>
1480 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1481 by the current fiber.
1482 </p></dd>
1483<dt><span class="term">Throws:</span></dt>
1484<dd><p>
1485 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
1486 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
1487 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
1488 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
1489 of execution.
1490 </p></dd>
1491<dt><span class="term">Note:</span></dt>
1492<dd><p>
1493 The Precondition is a bit dense. It merely states that all the
1494 fibers concurrently calling <code class="computeroutput"><span class="identifier">wait</span></code>
1495 on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1496 must wait on <code class="computeroutput"><span class="identifier">lk</span></code>
1497 objects governing the <span class="emphasis"><em>same</em></span> <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a>.
1498 Three distinct objects are involved in any <code class="computeroutput">condition_variable_any::wait()</code> call:
1499 the <code class="computeroutput">condition_variable_any</code> itself, the <code class="computeroutput"><span class="identifier">mutex</span></code>
1500 coordinating access between fibers and a local lock object (e.g.
1501 <a href="http://en.cppreference.com/w/cpp/thread/unique_lock" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span></code></a>). In general,
1502 you can partition the lifespan of a given <code class="computeroutput">condition_variable_any</code> instance
1503 into periods with one or more fibers waiting on it, separated
1504 by periods when no fibers are waiting on it. When more than one
1505 fiber is waiting on that <code class="computeroutput">condition_variable_any</code>, all must pass
1506 lock objects referencing the <span class="emphasis"><em>same</em></span> <code class="computeroutput"><span class="identifier">mutex</span></code> instance.
1507 </p></dd>
1508</dl>
1509</div>
1510<p>
1511 </p>
1512<h5>
1513<a name="condition_variable_any_wait_until_bridgehead"></a>
1514 <span><a name="condition_variable_any_wait_until"></a></span>
1515 <a class="link" href="pooled_fixedsize.html#condition_variable_any_wait_until">Templated
1516 member function <code class="computeroutput">wait_until</code>()</a>
1517</h5>
1518<p>
1519 </p>
1520<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
1521<span class="identifier">cv_status</span> <span class="identifier">wait_until</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1522 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>
1523
1524<span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1525<span class="keyword">bool</span> <span class="identifier">wait_until</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1526 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">abs_time</span><span class="special">,</span>
1527 <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
1528</pre>
1529<div class="variablelist">
1530<p class="title"><b></b></p>
1531<dl>
1532<dt><span class="term">Precondition:</span></dt>
1533<dd><p>
1534 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1535 by the current fiber, and either no other fiber is currently
1536 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
1537 or the execution of the <code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code> member function on the <code class="computeroutput"><span class="identifier">lk</span></code> objects supplied in the
1538 calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
1539 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1540 <code class="computeroutput"><span class="identifier">wait_until</span></code> in
1541 all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
1542 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">mutex</span><span class="special">()</span></code>
1543 for this call to <code class="computeroutput"><span class="identifier">wait_until</span></code>.
1544 </p></dd>
1545<dt><span class="term">Effects:</span></dt>
1546<dd>
1547<p>
1548 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
1549 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
1550 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>,
1551 when the system time would be equal to or later than the specified
1552 <code class="computeroutput"><span class="identifier">abs_time</span></code>. When
1553 the fiber is unblocked (for whatever reason), the lock is reacquired
1554 by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait_until</span></code> returns. The lock
1555 is also reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
1556 an exception. The member function accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1557 is shorthand for:
1558</p>
1559<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
1560 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span> <span class="special">==</span> <span class="identifier">wait_until</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">abs_time</span><span class="special">)</span> <span class="special">)</span>
1561 <span class="keyword">return</span> <span class="identifier">pred</span><span class="special">();</span>
1562<span class="special">}</span>
1563<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
1564</pre>
1565<p>
1566 That is, even if <code class="computeroutput"><span class="identifier">wait_until</span><span class="special">()</span></code> times out, it can still return
1567 <code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="identifier">pred</span><span class="special">()</span></code>
1568 returns <code class="computeroutput"><span class="keyword">true</span></code> at
1569 that time.
1570 </p>
1571</dd>
1572<dt><span class="term">Postcondition:</span></dt>
1573<dd><p>
1574 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1575 by the current fiber.
1576 </p></dd>
1577<dt><span class="term">Throws:</span></dt>
1578<dd><p>
1579 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
1580 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
1581 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
1582 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
1583 of execution or timeout-related exceptions.
1584 </p></dd>
1585<dt><span class="term">Returns:</span></dt>
1586<dd><p>
1587 The overload without <code class="computeroutput"><span class="identifier">pred</span></code>
1588 returns <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">no_timeout</span></code>
1589 if awakened by <code class="computeroutput"><span class="identifier">notify_one</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">notify_all</span><span class="special">()</span></code>, or <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span></code>
1590 if awakened because the system time is past <code class="computeroutput"><span class="identifier">abs_time</span></code>.
1591 </p></dd>
1592<dt><span class="term">Returns:</span></dt>
1593<dd><p>
1594 The overload accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1595 returns <code class="computeroutput"><span class="keyword">false</span></code> if
1596 the call is returning because the time specified by <code class="computeroutput"><span class="identifier">abs_time</span></code> was reached and the
1597 predicate returns <code class="computeroutput"><span class="keyword">false</span></code>,
1598 <code class="computeroutput"><span class="keyword">true</span></code> otherwise.
1599 </p></dd>
1600<dt><span class="term">Note:</span></dt>
1601<dd><p>
1602 See <span class="bold"><strong>Note</strong></span> for <a class="link" href="pooled_fixedsize.html#condition_variable_any_wait"> <code class="computeroutput">condition_variable_any::wait()</code></a>.
1603 </p></dd>
1604</dl>
1605</div>
1606<p>
1607 </p>
1608<h5>
1609<a name="condition_variable_any_wait_for_bridgehead"></a>
1610 <span><a name="condition_variable_any_wait_for"></a></span>
1611 <a class="link" href="pooled_fixedsize.html#condition_variable_any_wait_for">Templated
1612 member function <code class="computeroutput">wait_for</code>()</a>
1613</h5>
1614<p>
1615 </p>
1616<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
1617<span class="identifier">cv_status</span> <span class="identifier">wait_for</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1618 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
1619
1620<span class="keyword">template</span><span class="special">&lt;</span> typename LockType, typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1621<span class="keyword">bool</span> <span class="identifier">wait_for</span><span class="special">(</span> LockType <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1622 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rel_time</span><span class="special">,</span>
1623 <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
1624</pre>
1625<div class="variablelist">
1626<p class="title"><b></b></p>
1627<dl>
1628<dt><span class="term">Precondition:</span></dt>
1629<dd><p>
1630 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1631 by the current fiber, and either no other fiber is currently
1632 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
1633 or the execution of the <code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code> member function on the <code class="computeroutput"><span class="identifier">lk</span></code> objects supplied in the
1634 calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
1635 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1636 <code class="computeroutput"><span class="identifier">wait_until</span></code> in
1637 all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
1638 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">mutex</span><span class="special">()</span></code>
1639 for this call to <code class="computeroutput"><span class="identifier">wait_for</span></code>.
1640 </p></dd>
1641<dt><span class="term">Effects:</span></dt>
1642<dd>
1643<p>
1644 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
1645 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
1646 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>,
1647 when a time interval equal to or greater than the specified
1648 <code class="computeroutput"><span class="identifier">rel_time</span></code> has
1649 elapsed. When the fiber is unblocked (for whatever reason), the
1650 lock is reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait</span></code> returns. The lock is also
1651 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
1652 an exception. The <code class="computeroutput"><span class="identifier">wait_for</span><span class="special">()</span></code> member function accepting
1653 <code class="computeroutput"><span class="identifier">pred</span></code> is shorthand
1654 for:
1655</p>
1656<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
1657 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span> <span class="special">==</span> <span class="identifier">wait_for</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">rel_time</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
1658 <span class="keyword">return</span> <span class="identifier">pred</span><span class="special">();</span>
1659 <span class="special">}</span>
1660<span class="special">}</span>
1661<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
1662</pre>
1663<p>
1664 (except of course that <code class="computeroutput"><span class="identifier">rel_time</span></code>
1665 is adjusted for each iteration). The point is that, even if
1666 <code class="computeroutput"><span class="identifier">wait_for</span><span class="special">()</span></code>
1667 times out, it can still return <code class="computeroutput"><span class="keyword">true</span></code>
1668 if <code class="computeroutput"><span class="identifier">pred</span><span class="special">()</span></code>
1669 returns <code class="computeroutput"><span class="keyword">true</span></code> at
1670 that time.
1671 </p>
1672</dd>
1673<dt><span class="term">Postcondition:</span></dt>
1674<dd><p>
1675 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1676 by the current fiber.
1677 </p></dd>
1678<dt><span class="term">Throws:</span></dt>
1679<dd><p>
1680 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
1681 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
1682 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
1683 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
1684 of execution or timeout-related exceptions.
1685 </p></dd>
1686<dt><span class="term">Returns:</span></dt>
1687<dd><p>
1688 The overload without <code class="computeroutput"><span class="identifier">pred</span></code>
1689 returns <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">no_timeout</span></code>
1690 if awakened by <code class="computeroutput"><span class="identifier">notify_one</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">notify_all</span><span class="special">()</span></code>, or <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span></code>
1691 if awakened because at least <code class="computeroutput"><span class="identifier">rel_time</span></code>
1692 has elapsed.
1693 </p></dd>
1694<dt><span class="term">Returns:</span></dt>
1695<dd><p>
1696 The overload accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1697 returns <code class="computeroutput"><span class="keyword">false</span></code> if
1698 the call is returning because at least <code class="computeroutput"><span class="identifier">rel_time</span></code>
1699 has elapsed and the predicate returns <code class="computeroutput"><span class="keyword">false</span></code>,
1700 <code class="computeroutput"><span class="keyword">true</span></code> otherwise.
1701 </p></dd>
1702<dt><span class="term">Note:</span></dt>
1703<dd><p>
1704 See <span class="bold"><strong>Note</strong></span> for <a class="link" href="pooled_fixedsize.html#condition_variable_any_wait"> <code class="computeroutput">condition_variable_any::wait()</code></a>.
1705 </p></dd>
1706</dl>
1707</div>
1708<p>
1709 </p>
1710<h5>
1711<a name="class_condition_variable_bridgehead"></a>
1712 <span><a name="class_condition_variable"></a></span>
1713 <a class="link" href="pooled_fixedsize.html#class_condition_variable">Class
1714 <code class="computeroutput">condition_variable</code></a>
1715</h5>
1716<p>
1717 </p>
1718<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">condition_variable</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
1719
1720<span class="keyword">class</span> condition_variable <span class="special">{</span>
1721<span class="keyword">public</span><span class="special">:</span>
1722 condition_variable<span class="special">();</span>
1723 <span class="special">~</span>condition_variable<span class="special">();</span>
1724
1725 condition_variable<span class="special">(</span> condition_variable <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
1726 condition_variable <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> condition_variable <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
1727
1728 <span class="keyword">void</span> <span class="identifier">notify_one</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1729 <span class="keyword">void</span> <span class="identifier">notify_all</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1730
1731 void <span class="identifier">wait</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;);</span>
1732
1733 <span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Pred</span> <span class="special">&gt;</span>
1734 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;,</span> <span class="identifier">Pred</span><span class="special">);</span>
1735
1736 <span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
1737 <span class="identifier">cv_status</span> <span class="identifier">wait_until</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;,</span>
1738 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;);</span>
1739
1740 <span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1741 <span class="keyword">bool</span> <span class="identifier">wait_until</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;,</span>
1742 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;,</span>
1743 <span class="identifier">Pred</span><span class="special">);</span>
1744
1745 <span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
1746 <span class="identifier">cv_status</span> <span class="identifier">wait_for</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;,</span>
1747 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;);</span>
1748
1749 <span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1750 <span class="keyword">bool</span> <span class="identifier">wait_for</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;,</span>
1751 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;,</span>
1752 <span class="identifier">Pred</span><span class="special">);</span>
1753<span class="special">};</span>
1754</pre>
1755<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h7"></a>
1756 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.constructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.constructor0">Constructor</a>
1757 </h7><pre class="programlisting">condition_variable<span class="special">()</span>
1758</pre>
1759<div class="variablelist">
1760<p class="title"><b></b></p>
1761<dl>
1762<dt><span class="term">Effects:</span></dt>
1763<dd><p>
1764 Creates the object.
1765 </p></dd>
1766<dt><span class="term">Throws:</span></dt>
1767<dd><p>
1768 Nothing.
1769 </p></dd>
1770</dl>
1771</div>
1772<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.h8"></a>
1773 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.destructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.conditions.destructor0">Destructor</a>
1774 </h7><pre class="programlisting"><span class="special">~</span>condition_variable<span class="special">()</span>
1775</pre>
1776<div class="variablelist">
1777<p class="title"><b></b></p>
1778<dl>
1779<dt><span class="term">Precondition:</span></dt>
1780<dd><p>
1781 All fibers waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> have been notified by a call
1782 to <code class="computeroutput"><span class="identifier">notify_one</span></code>
1783 or <code class="computeroutput"><span class="identifier">notify_all</span></code>
1784 (though the respective calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
1785 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1786 <code class="computeroutput"><span class="identifier">wait_until</span></code> need
1787 not have returned).
1788 </p></dd>
1789<dt><span class="term">Effects:</span></dt>
1790<dd><p>
1791 Destroys the object.
1792 </p></dd>
1793</dl>
1794</div>
1795<p>
1796 </p>
1797<h5>
1798<a name="condition_variable_notify_one_bridgehead"></a>
1799 <span><a name="condition_variable_notify_one"></a></span>
1800 <a class="link" href="pooled_fixedsize.html#condition_variable_notify_one">Member
1801 function <code class="computeroutput">notify_one</code>()</a>
1802</h5>
1803<p>
1804 </p>
1805<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">notify_one</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1806</pre>
1807<div class="variablelist">
1808<p class="title"><b></b></p>
1809<dl>
1810<dt><span class="term">Effects:</span></dt>
1811<dd><p>
1812 If any fibers are currently <a class="link" href="../../overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>
1813 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1814 in a call to <code class="computeroutput"><span class="identifier">wait</span></code>,
1815 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1816 <code class="computeroutput"><span class="identifier">wait_until</span></code>, unblocks
1817 one of those fibers.
1818 </p></dd>
1819<dt><span class="term">Throws:</span></dt>
1820<dd><p>
1821 Nothing.
1822 </p></dd>
1823<dt><span class="term">Note:</span></dt>
1824<dd><p>
1825 It is arbitrary which waiting fiber is resumed.
1826 </p></dd>
1827</dl>
1828</div>
1829<p>
1830 </p>
1831<h5>
1832<a name="condition_variable_notify_all_bridgehead"></a>
1833 <span><a name="condition_variable_notify_all"></a></span>
1834 <a class="link" href="pooled_fixedsize.html#condition_variable_notify_all">Member
1835 function <code class="computeroutput">notify_all</code>()</a>
1836</h5>
1837<p>
1838 </p>
1839<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">notify_all</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
1840</pre>
1841<div class="variablelist">
1842<p class="title"><b></b></p>
1843<dl>
1844<dt><span class="term">Effects:</span></dt>
1845<dd><p>
1846 If any fibers are currently <a class="link" href="../../overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>
1847 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1848 in a call to <code class="computeroutput"><span class="identifier">wait</span></code>,
1849 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1850 <code class="computeroutput"><span class="identifier">wait_until</span></code>, unblocks
1851 all of those fibers.
1852 </p></dd>
1853<dt><span class="term">Throws:</span></dt>
1854<dd><p>
1855 Nothing.
1856 </p></dd>
1857<dt><span class="term">Note:</span></dt>
1858<dd><p>
1859 This is why a waiting fiber must <span class="emphasis"><em>also</em></span> check
1860 for the desired program state using a mechanism external to the
1861 <code class="computeroutput">condition_variable</code>, and retry the wait until that state is reached.
1862 A fiber waiting on a <code class="computeroutput">condition_variable</code> might well wake up a number
1863 of times before the desired state is reached.
1864 </p></dd>
1865</dl>
1866</div>
1867<p>
1868 </p>
1869<h5>
1870<a name="condition_variable_wait_bridgehead"></a>
1871 <span><a name="condition_variable_wait"></a></span>
1872 <a class="link" href="pooled_fixedsize.html#condition_variable_wait">Templated
1873 member function <code class="computeroutput">wait</code>()</a>
1874</h5>
1875<p>
1876 </p>
1877<pre class="programlisting">void <span class="identifier">wait</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">);</span>
1878
1879<span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Pred</span> <span class="special">&gt;</span>
1880<span class="keyword">void</span> <span class="identifier">wait</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
1881</pre>
1882<div class="variablelist">
1883<p class="title"><b></b></p>
1884<dl>
1885<dt><span class="term">Precondition:</span></dt>
1886<dd><p>
1887 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1888 by the current fiber, and either no other fiber is currently
1889 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
1890 or the execution of the <a href="http://en.cppreference.com/w/cpp/thread/unique_lock/mutex" target="_top"><code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code></a>
1891 member function on the <code class="computeroutput"><span class="identifier">lk</span></code>
1892 objects supplied in the calls to <code class="computeroutput"><span class="identifier">wait</span></code>
1893 in all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
1894 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">-&gt;</span><span class="identifier">mutex</span><span class="special">()</span></code>
1895 for this call to <code class="computeroutput"><span class="identifier">wait</span></code>.
1896 </p></dd>
1897<dt><span class="term">Effects:</span></dt>
1898<dd>
1899<p>
1900 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
1901 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
1902 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>.
1903 When the fiber is unblocked (for whatever reason), the lock is
1904 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait</span></code> returns. The lock is also
1905 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
1906 an exception. The member function accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1907 is shorthand for:
1908</p>
1909<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
1910 <span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">);</span>
1911<span class="special">}</span>
1912</pre>
1913<p>
1914 </p>
1915</dd>
1916<dt><span class="term">Postcondition:</span></dt>
1917<dd><p>
1918 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1919 by the current fiber.
1920 </p></dd>
1921<dt><span class="term">Throws:</span></dt>
1922<dd><p>
1923 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
1924 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
1925 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
1926 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
1927 of execution.
1928 </p></dd>
1929<dt><span class="term">Note:</span></dt>
1930<dd><p>
1931 The Precondition is a bit dense. It merely states that all the
1932 fibers concurrently calling <code class="computeroutput"><span class="identifier">wait</span></code>
1933 on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
1934 must wait on <code class="computeroutput"><span class="identifier">lk</span></code>
1935 objects governing the <span class="emphasis"><em>same</em></span> <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a>.
1936 Three distinct objects are involved in any <code class="computeroutput">condition_variable::wait()</code> call:
1937 the <code class="computeroutput">condition_variable</code> itself, the <code class="computeroutput"><span class="identifier">mutex</span></code>
1938 coordinating access between fibers and a local lock object (e.g.
1939 <a href="http://en.cppreference.com/w/cpp/thread/unique_lock" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span></code></a>). In general,
1940 you can partition the lifespan of a given <code class="computeroutput">condition_variable</code> instance
1941 into periods with one or more fibers waiting on it, separated
1942 by periods when no fibers are waiting on it. When more than one
1943 fiber is waiting on that <code class="computeroutput">condition_variable</code>, all must pass lock
1944 objects referencing the <span class="emphasis"><em>same</em></span> <code class="computeroutput"><span class="identifier">mutex</span></code> instance.
1945 </p></dd>
1946</dl>
1947</div>
1948<p>
1949 </p>
1950<h5>
1951<a name="condition_variable_wait_until_bridgehead"></a>
1952 <span><a name="condition_variable_wait_until"></a></span>
1953 <a class="link" href="pooled_fixedsize.html#condition_variable_wait_until">Templated
1954 member function <code class="computeroutput">wait_until</code>()</a>
1955</h5>
1956<p>
1957 </p>
1958<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
1959<span class="identifier">cv_status</span> <span class="identifier">wait_until</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1960 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">abs_time</span><span class="special">);</span>
1961
1962<span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
1963<span class="keyword">bool</span> <span class="identifier">wait_until</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
1964 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">abs_time</span><span class="special">,</span>
1965 <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
1966</pre>
1967<div class="variablelist">
1968<p class="title"><b></b></p>
1969<dl>
1970<dt><span class="term">Precondition:</span></dt>
1971<dd><p>
1972 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
1973 by the current fiber, and either no other fiber is currently
1974 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
1975 or the execution of the <code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code> member function on the <code class="computeroutput"><span class="identifier">lk</span></code> objects supplied in the
1976 calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
1977 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
1978 <code class="computeroutput"><span class="identifier">wait_until</span></code> in
1979 all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
1980 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">mutex</span><span class="special">()</span></code>
1981 for this call to <code class="computeroutput"><span class="identifier">wait_until</span></code>.
1982 </p></dd>
1983<dt><span class="term">Effects:</span></dt>
1984<dd>
1985<p>
1986 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
1987 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
1988 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>,
1989 when the system time would be equal to or later than the specified
1990 <code class="computeroutput"><span class="identifier">abs_time</span></code>. When
1991 the fiber is unblocked (for whatever reason), the lock is reacquired
1992 by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait_until</span></code> returns. The lock
1993 is also reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
1994 an exception. The member function accepting <code class="computeroutput"><span class="identifier">pred</span></code>
1995 is shorthand for:
1996</p>
1997<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
1998 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span> <span class="special">==</span> <span class="identifier">wait_until</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">abs_time</span><span class="special">)</span> <span class="special">)</span>
1999 <span class="keyword">return</span> <span class="identifier">pred</span><span class="special">();</span>
2000<span class="special">}</span>
2001<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
2002</pre>
2003<p>
2004 That is, even if <code class="computeroutput"><span class="identifier">wait_until</span><span class="special">()</span></code> times out, it can still return
2005 <code class="computeroutput"><span class="keyword">true</span></code> if <code class="computeroutput"><span class="identifier">pred</span><span class="special">()</span></code>
2006 returns <code class="computeroutput"><span class="keyword">true</span></code> at
2007 that time.
2008 </p>
2009</dd>
2010<dt><span class="term">Postcondition:</span></dt>
2011<dd><p>
2012 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
2013 by the current fiber.
2014 </p></dd>
2015<dt><span class="term">Throws:</span></dt>
2016<dd><p>
2017 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
2018 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2019 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
2020 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
2021 of execution or timeout-related exceptions.
2022 </p></dd>
2023<dt><span class="term">Returns:</span></dt>
2024<dd><p>
2025 The overload without <code class="computeroutput"><span class="identifier">pred</span></code>
2026 returns <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">no_timeout</span></code>
2027 if awakened by <code class="computeroutput"><span class="identifier">notify_one</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">notify_all</span><span class="special">()</span></code>, or <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span></code>
2028 if awakened because the system time is past <code class="computeroutput"><span class="identifier">abs_time</span></code>.
2029 </p></dd>
2030<dt><span class="term">Returns:</span></dt>
2031<dd><p>
2032 The overload accepting <code class="computeroutput"><span class="identifier">pred</span></code>
2033 returns <code class="computeroutput"><span class="keyword">false</span></code> if
2034 the call is returning because the time specified by <code class="computeroutput"><span class="identifier">abs_time</span></code> was reached and the
2035 predicate returns <code class="computeroutput"><span class="keyword">false</span></code>,
2036 <code class="computeroutput"><span class="keyword">true</span></code> otherwise.
2037 </p></dd>
2038<dt><span class="term">Note:</span></dt>
2039<dd><p>
2040 See <span class="bold"><strong>Note</strong></span> for <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a>.
2041 </p></dd>
2042</dl>
2043</div>
2044<p>
2045 </p>
2046<h5>
2047<a name="condition_variable_wait_for_bridgehead"></a>
2048 <span><a name="condition_variable_wait_for"></a></span>
2049 <a class="link" href="pooled_fixedsize.html#condition_variable_wait_for">Templated
2050 member function <code class="computeroutput">wait_for</code>()</a>
2051</h5>
2052<p>
2053 </p>
2054<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2055<span class="identifier">cv_status</span> <span class="identifier">wait_for</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
2056 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rel_time</span><span class="special">);</span>
2057
2058<span class="keyword">template</span><span class="special">&lt;</span> typename <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Pred</span> <span class="special">&gt;</span>
2059<span class="keyword">bool</span> <span class="identifier">wait_for</span><span class="special">(</span> std::unique_lock&lt; mutex &gt; <span class="special">&amp;</span> <span class="identifier">lk</span><span class="special">,</span>
2060 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rel_time</span><span class="special">,</span>
2061 <span class="identifier">Pred</span> <span class="identifier">pred</span><span class="special">);</span>
2062</pre>
2063<div class="variablelist">
2064<p class="title"><b></b></p>
2065<dl>
2066<dt><span class="term">Precondition:</span></dt>
2067<dd><p>
2068 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
2069 by the current fiber, and either no other fiber is currently
2070 waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>,
2071 or the execution of the <code class="computeroutput"><span class="identifier">mutex</span><span class="special">()</span></code> member function on the <code class="computeroutput"><span class="identifier">lk</span></code> objects supplied in the
2072 calls to <code class="computeroutput"><span class="identifier">wait</span></code>,
2073 <code class="computeroutput"><span class="identifier">wait_for</span></code> or
2074 <code class="computeroutput"><span class="identifier">wait_until</span></code> in
2075 all the fibers currently waiting on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> would return the same value
2076 as <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">mutex</span><span class="special">()</span></code>
2077 for this call to <code class="computeroutput"><span class="identifier">wait_for</span></code>.
2078 </p></dd>
2079<dt><span class="term">Effects:</span></dt>
2080<dd>
2081<p>
2082 Atomically call <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">()</span></code> and blocks the current fiber.
2083 The fiber will unblock when notified by a call to <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_one</span><span class="special">()</span></code>
2084 or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">notify_all</span><span class="special">()</span></code>,
2085 when a time interval equal to or greater than the specified
2086 <code class="computeroutput"><span class="identifier">rel_time</span></code> has
2087 elapsed. When the fiber is unblocked (for whatever reason), the
2088 lock is reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> before the call to <code class="computeroutput"><span class="identifier">wait</span></code> returns. The lock is also
2089 reacquired by invoking <code class="computeroutput"><span class="identifier">lk</span><span class="special">.</span><span class="identifier">lock</span><span class="special">()</span></code> if the function exits with
2090 an exception. The <code class="computeroutput"><span class="identifier">wait_for</span><span class="special">()</span></code> member function accepting
2091 <code class="computeroutput"><span class="identifier">pred</span></code> is shorthand
2092 for:
2093</p>
2094<pre class="programlisting"><span class="keyword">while</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">pred</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
2095 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span> <span class="special">==</span> <span class="identifier">wait_for</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">rel_time</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
2096 <span class="keyword">return</span> <span class="identifier">pred</span><span class="special">();</span>
2097 <span class="special">}</span>
2098<span class="special">}</span>
2099<span class="keyword">return</span> <span class="keyword">true</span><span class="special">;</span>
2100</pre>
2101<p>
2102 (except of course that <code class="computeroutput"><span class="identifier">rel_time</span></code>
2103 is adjusted for each iteration). The point is that, even if
2104 <code class="computeroutput"><span class="identifier">wait_for</span><span class="special">()</span></code>
2105 times out, it can still return <code class="computeroutput"><span class="keyword">true</span></code>
2106 if <code class="computeroutput"><span class="identifier">pred</span><span class="special">()</span></code>
2107 returns <code class="computeroutput"><span class="keyword">true</span></code> at
2108 that time.
2109 </p>
2110</dd>
2111<dt><span class="term">Postcondition:</span></dt>
2112<dd><p>
2113 <code class="computeroutput"><span class="identifier">lk</span></code> is locked
2114 by the current fiber.
2115 </p></dd>
2116<dt><span class="term">Throws:</span></dt>
2117<dd><p>
2118 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
2119 an error occurs, <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2120 if the wait was interrupted by a call to <a class="link" href="../../fiber_mgmt/fiber.html#fiber_interrupt"> <code class="computeroutput">fiber::interrupt()</code></a> on
2121 the <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> object associated with the current fiber
2122 of execution or timeout-related exceptions.
2123 </p></dd>
2124<dt><span class="term">Returns:</span></dt>
2125<dd><p>
2126 The overload without <code class="computeroutput"><span class="identifier">pred</span></code>
2127 returns <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">no_timeout</span></code>
2128 if awakened by <code class="computeroutput"><span class="identifier">notify_one</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">notify_all</span><span class="special">()</span></code>, or <code class="computeroutput"><span class="identifier">cv_status</span><span class="special">::</span><span class="identifier">timeout</span></code>
2129 if awakened because at least <code class="computeroutput"><span class="identifier">rel_time</span></code>
2130 has elapsed.
2131 </p></dd>
2132<dt><span class="term">Returns:</span></dt>
2133<dd><p>
2134 The overload accepting <code class="computeroutput"><span class="identifier">pred</span></code>
2135 returns <code class="computeroutput"><span class="keyword">false</span></code> if
2136 the call is returning because at least <code class="computeroutput"><span class="identifier">rel_time</span></code>
2137 has elapsed and the predicate returns <code class="computeroutput"><span class="keyword">false</span></code>,
2138 <code class="computeroutput"><span class="keyword">true</span></code> otherwise.
2139 </p></dd>
2140<dt><span class="term">Note:</span></dt>
2141<dd><p>
2142 See <span class="bold"><strong>Note</strong></span> for <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a>.
2143 </p></dd>
2144</dl>
2145</div>
2146</div>
2147<div class="section">
2148<div class="titlepage"><div><div><h6 class="title">
2149<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers" title="Barriers">Barriers</a>
2150</h6></div></div></div>
2151<p>
2152 A barrier is a concept also known as a <span class="emphasis"><em>rendezvous</em></span>,
2153 it is a synchronization point between multiple contexts of execution
2154 (fibers). The barrier is configured for a particular number of fibers
2155 (<code class="computeroutput"><span class="identifier">n</span></code>), and as fibers
2156 reach the barrier they must wait until all <code class="computeroutput"><span class="identifier">n</span></code>
2157 fibers have arrived. Once the <code class="computeroutput"><span class="identifier">n</span></code>-th
2158 fiber has reached the barrier, all the waiting fibers can proceed,
2159 and the barrier is reset.
2160 </p>
2161<p>
2162 The fact that the barrier automatically resets is significant. Consider
2163 a case in which you launch some number of fibers and want to wait only
2164 until the first of them has completed. You might be tempted to use
2165 a <code class="computeroutput"><span class="identifier">barrier</span><span class="special">(</span><span class="number">2</span><span class="special">)</span></code> as
2166 the synchronization mechanism, making each new fiber call its <a class="link" href="pooled_fixedsize.html#barrier_wait"> <code class="computeroutput">barrier::wait()</code></a> method,
2167 then calling <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
2168 in the launching fiber to wait until the first other fiber completes.
2169 </p>
2170<p>
2171 That will in fact unblock the launching fiber. The unfortunate part
2172 is that it will continue blocking the <span class="emphasis"><em>remaining</em></span>
2173 fibers.
2174 </p>
2175<p>
2176 Consider the following scenario:
2177 </p>
2178<div class="orderedlist"><ol class="orderedlist" type="1">
2179<li class="listitem">
2180 Fiber <span class="quote">&#8220;<span class="quote">main</span>&#8221;</span> launches fibers A, B, C and D, then calls
2181 <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>.
2182 </li>
2183<li class="listitem">
2184 Fiber C finishes first and likewise calls <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>.
2185 </li>
2186<li class="listitem">
2187 Fiber <span class="quote">&#8220;<span class="quote">main</span>&#8221;</span> is unblocked, as desired.
2188 </li>
2189<li class="listitem">
2190 Fiber B calls <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>. Fiber B is <span class="emphasis"><em>blocked!</em></span>
2191 </li>
2192<li class="listitem">
2193 Fiber A calls <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>. Fibers A and B are unblocked.
2194 </li>
2195<li class="listitem">
2196 Fiber D calls <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>. Fiber D is blocked indefinitely.
2197 </li>
2198</ol></div>
2199<p>
2200 (See also <a class="link" href="pooled_fixedsize.html#wait_first_simple_section">when_any, simple
2201 completion</a>.)
2202 </p>
2203<div class="note"><table border="0" summary="Note">
2204<tr>
2205<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
2206<th align="left">Note</th>
2207</tr>
2208<tr><td align="left" valign="top"><p>
2209 It is unwise to tie the lifespan of a barrier to any one of its participating
2210 fibers. Although conceptually all waiting fibers awaken <span class="quote">&#8220;<span class="quote">simultaneously,</span>&#8221;</span>
2211 because of the nature of fibers, in practice they will awaken one
2212 by one in indeterminate order.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.f0" class="footnote">2</a>]</sup> The rest of the waiting fibers will still be blocked
2213 in <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>,
2214 which must, before returning, access data members in the barrier
2215 object.
2216 </p></td></tr>
2217</table></div>
2218<p>
2219 </p>
2220<h5>
2221<a name="class_barrier_bridgehead"></a>
2222 <span><a name="class_barrier"></a></span>
2223 <a class="link" href="pooled_fixedsize.html#class_barrier">Class <code class="computeroutput">barrier</code></a>
2224</h5>
2225<p>
2226 </p>
2227<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">barrier</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2228
2229<span class="keyword">class</span> <span class="identifier">barrier</span> <span class="special">{</span>
2230<span class="keyword">public</span><span class="special">:</span>
2231 <span class="keyword">explicit</span> <span class="identifier">barrier</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span><span class="special">);</span>
2232
2233 <span class="identifier">barrier</span><span class="special">(</span> <span class="identifier">barrier</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2234 <span class="identifier">barrier</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">barrier</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2235
2236 <span class="keyword">bool</span> <span class="identifier">wait</span><span class="special">();</span>
2237<span class="special">};</span>
2238</pre>
2239<p>
2240 Instances of <a class="link" href="pooled_fixedsize.html#class_barrier"> <code class="computeroutput">barrier</code></a> are not copyable or movable.
2241 </p>
2242<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.h0"></a>
2243 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.constructor">Constructor</a>
2244 </h7><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">barrier</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">initial</span><span class="special">);</span>
2245</pre>
2246<div class="variablelist">
2247<p class="title"><b></b></p>
2248<dl>
2249<dt><span class="term">Effects:</span></dt>
2250<dd><p>
2251 Construct a barrier for <code class="computeroutput"><span class="identifier">initial</span></code>
2252 fibers.
2253 </p></dd>
2254<dt><span class="term">Throws:</span></dt>
2255<dd><p>
2256 <code class="computeroutput"><span class="identifier">fiber_error</span></code>
2257 </p></dd>
2258<dt><span class="term">Error Conditions:</span></dt>
2259<dd><p>
2260 <span class="bold"><strong>invalid_argument</strong></span>: if <code class="computeroutput"><span class="identifier">initial</span></code> is zero.
2261 </p></dd>
2262</dl>
2263</div>
2264<p>
2265 </p>
2266<h5>
2267<a name="barrier_wait_bridgehead"></a>
2268 <span><a name="barrier_wait"></a></span>
2269 <a class="link" href="pooled_fixedsize.html#barrier_wait">Member function <code class="computeroutput">wait</code>()</a>
2270</h5>
2271<p>
2272 </p>
2273<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">wait</span><span class="special">();</span>
2274</pre>
2275<div class="variablelist">
2276<p class="title"><b></b></p>
2277<dl>
2278<dt><span class="term">Effects:</span></dt>
2279<dd><p>
2280 Block until <code class="computeroutput"><span class="identifier">initial</span></code>
2281 fibers have called <code class="computeroutput"><span class="identifier">wait</span></code>
2282 on <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
2283 When the <code class="computeroutput"><span class="identifier">initial</span></code>-th
2284 fiber calls <code class="computeroutput"><span class="identifier">wait</span></code>,
2285 all waiting fibers are unblocked, and the barrier is reset.
2286 </p></dd>
2287<dt><span class="term">Returns:</span></dt>
2288<dd><p>
2289 <code class="computeroutput"><span class="keyword">true</span></code> for exactly
2290 one fiber from each batch of waiting fibers, <code class="computeroutput"><span class="keyword">false</span></code>
2291 otherwise.
2292 </p></dd>
2293<dt><span class="term">Throws:</span></dt>
2294<dd><p>
2295 <code class="computeroutput"><span class="identifier">fiber_error</span></code>
2296 </p></dd>
2297<dt><span class="term">Notes:</span></dt>
2298<dd><p>
2299 <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
2300 is one of the predefined <a class="link" href="../../fiber_mgmt.html#interruption"><span class="emphasis"><em>interruption-points</em></span></a>.
2301 </p></dd>
2302</dl>
2303</div>
2304</div>
2305<div class="section">
2306<div class="titlepage"><div><div><h6 class="title">
2307<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels" title="Channels">Channels</a>
2308</h6></div></div></div>
2309<p>
2310 <span class="bold"><strong>Boost.Fiber</strong></span> provides a bounded and
2311 a unbounded channel suitable to synchonize fibers via message passing.
2312 </p>
2313<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
2314
2315<span class="keyword">void</span> <span class="identifier">send</span><span class="special">(</span> <span class="identifier">channel_t</span> <span class="special">&amp;</span> <span class="identifier">channel</span><span class="special">)</span> <span class="special">{</span>
2316 <span class="keyword">for</span> <span class="special">(</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">5</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
2317 <span class="identifier">channel</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">i</span><span class="special">);</span>
2318 <span class="special">}</span>
2319 <span class="identifier">channel</span><span class="special">.</span><span class="identifier">close</span><span class="special">();</span>
2320<span class="special">}</span>
2321
2322<span class="keyword">void</span> <span class="identifier">recv</span><span class="special">(</span> <span class="identifier">channel_t</span> <span class="special">&amp;</span> <span class="identifier">channel</span><span class="special">)</span> <span class="special">{</span>
2323 <span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
2324 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">.</span><span class="identifier">pop</span><span class="special">(</span><span class="identifier">i</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
2325 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"received "</span> <span class="special">&lt;&lt;</span> <span class="identifier">i</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
2326 <span class="special">}</span>
2327<span class="special">}</span>
2328
2329<span class="identifier">channel_t</span> <span class="identifier">channel</span><span class="special">;</span>
2330<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f1</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span> <span class="identifier">send</span><span class="special">,</span> <span class="identifier">ref</span><span class="special">(</span> <span class="identifier">channel</span><span class="special">)</span> <span class="special">)</span> <span class="special">);</span>
2331<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">f2</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span> <span class="identifier">recv</span><span class="special">,</span> <span class="identifier">ref</span><span class="special">(</span> <span class="identifier">channel</span><span class="special">)</span> <span class="special">)</span> <span class="special">);</span>
2332
2333<span class="identifier">f1</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
2334<span class="identifier">f2</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
2335</pre>
2336<a name="class_channel_op_status"></a><h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h0"></a>
2337 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.enumeration__code__phrase_role__identifier__channel_op_status__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.enumeration__code__phrase_role__identifier__channel_op_status__phrase___code_">Enumeration
2338 <code class="computeroutput"><span class="identifier">channel_op_status</span></code></a>
2339 </h7><p>
2340 channel operations return the state of the channel.
2341 </p>
2342<pre class="programlisting"><span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">channel_op_status</span> <span class="special">{</span>
2343 <span class="identifier">success</span><span class="special">,</span>
2344 <span class="identifier">empty</span><span class="special">,</span>
2345 <span class="identifier">full</span><span class="special">,</span>
2346 <span class="identifier">closed</span><span class="special">,</span>
2347 <span class="identifier">timeout</span>
2348<span class="special">};</span>
2349</pre>
2350<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h1"></a>
2351 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__success__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__success__phrase___code_"><code class="computeroutput"><span class="identifier">success</span></code></a>
2352 </h7><div class="variablelist">
2353<p class="title"><b></b></p>
2354<dl>
2355<dt><span class="term">Effects:</span></dt>
2356<dd><p>
2357 Operation was successful.
2358 </p></dd>
2359</dl>
2360</div>
2361<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h2"></a>
2362 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__empty__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__empty__phrase___code_"><code class="computeroutput"><span class="identifier">empty</span></code></a>
2363 </h7><div class="variablelist">
2364<p class="title"><b></b></p>
2365<dl>
2366<dt><span class="term">Effects:</span></dt>
2367<dd><p>
2368 channel is empty, operation failed.
2369 </p></dd>
2370</dl>
2371</div>
2372<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h3"></a>
2373 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__full__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__full__phrase___code_"><code class="computeroutput"><span class="identifier">full</span></code></a>
2374 </h7><div class="variablelist">
2375<p class="title"><b></b></p>
2376<dl>
2377<dt><span class="term">Effects:</span></dt>
2378<dd><p>
2379 channel is full, operation failed.
2380 </p></dd>
2381</dl>
2382</div>
2383<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h4"></a>
2384 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__closed__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__closed__phrase___code_"><code class="computeroutput"><span class="identifier">closed</span></code></a>
2385 </h7><div class="variablelist">
2386<p class="title"><b></b></p>
2387<dl>
2388<dt><span class="term">Effects:</span></dt>
2389<dd><p>
2390 channel is closed, operation failed.
2391 </p></dd>
2392</dl>
2393</div>
2394<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h5"></a>
2395 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__timeout__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels._code__phrase_role__identifier__timeout__phrase___code_"><code class="computeroutput"><span class="identifier">timeout</span></code></a>
2396 </h7><div class="variablelist">
2397<p class="title"><b></b></p>
2398<dl>
2399<dt><span class="term">Effects:</span></dt>
2400<dd><p>
2401 The operation did not become ready before specified timeout elapsed.
2402 </p></dd>
2403</dl>
2404</div>
2405<p>
2406 </p>
2407<h5>
2408<a name="class_unbounded_channel_bridgehead"></a>
2409 <span><a name="class_unbounded_channel"></a></span>
2410 <a class="link" href="pooled_fixedsize.html#class_unbounded_channel">Template
2411 <code class="computeroutput">unbounded_channel&lt;&gt;</code></a>
2412</h5>
2413<p>
2414 </p>
2415<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">unbounded_channel</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2416
2417<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">=</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span></code></a> <span class="special">&gt;</span>
2418<span class="keyword">class</span> <span class="identifier">unbounded_channel</span> <span class="special">{</span>
2419<span class="keyword">public</span><span class="special">:</span>
2420 <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">value_type</span><span class="special">;</span>
2421
2422 <span class="keyword">explicit</span> <span class="identifier">unbounded_channel</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
2423
2424 <span class="identifier">unbounded_channel</span><span class="special">(</span> <span class="identifier">unbounded_channel</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2425 <span class="identifier">unbounded_channel</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">unbounded_channel</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2426
2427 <span class="keyword">void</span> <span class="identifier">close</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
2428
2429 <span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2430 <span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2431
2432 <span class="identifier">channel_op_status</span> <span class="identifier">pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2433 <span class="identifier">value_type</span> <span class="identifier">value_pop</span><span class="special">();</span>
2434 <span class="identifier">channel_op_status</span> <span class="identifier">try_pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2435 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2436 <span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_for</span><span class="special">(</span>
2437 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2438 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2439 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2440 <span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_until</span><span class="special">(</span>
2441 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2442 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2443<span class="special">};</span>
2444</pre>
2445<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h6"></a>
2446 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.constructor">Constructor</a>
2447 </h7><pre class="programlisting"><span class="keyword">explicit</span> <span class="identifier">unbounded_channel</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
2448</pre>
2449<div class="variablelist">
2450<p class="title"><b></b></p>
2451<dl>
2452<dt><span class="term">Effects:</span></dt>
2453<dd><p>
2454 Constructs an object of class <code class="computeroutput"><span class="identifier">unbounded_channel</span></code>.
2455 Internal nodes are allocated using <code class="computeroutput"><span class="identifier">alloc</span></code>
2456 - C++11-allocators are supported.
2457 </p></dd>
2458<dt><span class="term">Throws:</span></dt>
2459<dd><p>
2460 Nothing.
2461 </p></dd>
2462<dt><span class="term">See also:</span></dt>
2463<dd><p>
2464 <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> concept,
2465 <a href="http://en.cppreference.com/w/cpp/memory/allocator" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span>
2466 <span class="identifier">T</span> <span class="special">&gt;</span></code></a>
2467 </p></dd>
2468</dl>
2469</div>
2470<p>
2471 </p>
2472<h5>
2473<a name="unbounded_channel_close_bridgehead"></a>
2474 <span><a name="unbounded_channel_close"></a></span>
2475 <a class="link" href="pooled_fixedsize.html#unbounded_channel_close">Member
2476 function <code class="computeroutput">close</code>()</a>
2477</h5>
2478<p>
2479 </p>
2480<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">close</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
2481</pre>
2482<div class="variablelist">
2483<p class="title"><b></b></p>
2484<dl>
2485<dt><span class="term">Effects:</span></dt>
2486<dd><p>
2487 Deactivates the channel. No values can be put after calling
2488 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">()</span></code>.
2489 Fibers blocked in <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> will return <code class="computeroutput"><span class="identifier">closed</span></code>.
2490 Fibers blocked in <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code> will receive an exception.
2491 </p></dd>
2492<dt><span class="term">Throws:</span></dt>
2493<dd><p>
2494 Nothing.
2495 </p></dd>
2496<dt><span class="term">Note:</span></dt>
2497<dd><p>
2498 <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>
2499 is like closing a pipe. It informs waiting consumers that no
2500 more values will arrive.
2501 </p></dd>
2502</dl>
2503</div>
2504<p>
2505 </p>
2506<h5>
2507<a name="unbounded_channel_push_bridgehead"></a>
2508 <span><a name="unbounded_channel_push"></a></span>
2509 <a class="link" href="pooled_fixedsize.html#unbounded_channel_push">Member
2510 function <code class="computeroutput">push</code>()</a>
2511</h5>
2512<p>
2513 </p>
2514<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2515<span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2516</pre>
2517<div class="variablelist">
2518<p class="title"><b></b></p>
2519<dl>
2520<dt><span class="term">Effects:</span></dt>
2521<dd><p>
2522 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
2523 Otherwise enqueues the value in the channel, wakes up a fiber
2524 blocked on <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> and returns <code class="computeroutput"><span class="identifier">success</span></code>.
2525 </p></dd>
2526<dt><span class="term">Throws:</span></dt>
2527<dd><p>
2528 Exceptions thrown by memory allocation and copying or moving
2529 <code class="computeroutput"><span class="identifier">va</span></code>.
2530 </p></dd>
2531</dl>
2532</div>
2533<p>
2534 </p>
2535<h5>
2536<a name="unbounded_channel_pop_bridgehead"></a>
2537 <span><a name="unbounded_channel_pop"></a></span>
2538 <a class="link" href="pooled_fixedsize.html#unbounded_channel_pop">Member
2539 function <code class="computeroutput">pop</code>()</a>
2540</h5>
2541<p>
2542 </p>
2543<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2544</pre>
2545<div class="variablelist">
2546<p class="title"><b></b></p>
2547<dl>
2548<dt><span class="term">Effects:</span></dt>
2549<dd><p>
2550 Dequeues a value from the channel. If the channel is empty, the
2551 fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
2552 (return value <code class="computeroutput"><span class="identifier">success</span></code>
2553 and <code class="computeroutput"><span class="identifier">va</span></code> contains
2554 dequeued value) or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>).
2555 </p></dd>
2556<dt><span class="term">Throws:</span></dt>
2557<dd><p>
2558 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2559 </p></dd>
2560</dl>
2561</div>
2562<p>
2563 </p>
2564<h5>
2565<a name="unbounded_channel_value_pop_bridgehead"></a>
2566 <span><a name="unbounded_channel_value_pop"></a></span>
2567 <a class="link" href="pooled_fixedsize.html#unbounded_channel_value_pop">Member
2568 function <code class="computeroutput">value_pop</code>()</a>
2569</h5>
2570<p>
2571 </p>
2572<pre class="programlisting"><span class="identifier">value_type</span> <span class="identifier">value_pop</span><span class="special">();</span>
2573</pre>
2574<div class="variablelist">
2575<p class="title"><b></b></p>
2576<dl>
2577<dt><span class="term">Effects:</span></dt>
2578<dd><p>
2579 Dequeues a value from the channel. If the channel is empty, the
2580 fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
2581 or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (which throws an exception).
2582 </p></dd>
2583<dt><span class="term">Throws:</span></dt>
2584<dd><p>
2585 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
2586 <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
2587 is closed or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2588 </p></dd>
2589<dt><span class="term">Error conditions:</span></dt>
2590<dd><p>
2591 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">errc</span><span class="special">::</span><span class="identifier">operation_not_permitted</span></code>
2592 </p></dd>
2593</dl>
2594</div>
2595<p>
2596 </p>
2597<h5>
2598<a name="unbounded_channel_try_pop_bridgehead"></a>
2599 <span><a name="unbounded_channel_try_pop"></a></span>
2600 <a class="link" href="pooled_fixedsize.html#unbounded_channel_try_pop">Member
2601 function <code class="computeroutput">try_pop</code>()</a>
2602</h5>
2603<p>
2604 </p>
2605<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">try_pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2606</pre>
2607<div class="variablelist">
2608<p class="title"><b></b></p>
2609<dl>
2610<dt><span class="term">Effects:</span></dt>
2611<dd><p>
2612 If channel is empty, returns <code class="computeroutput"><span class="identifier">empty</span></code>.
2613 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
2614 Otherwise it returns <code class="computeroutput"><span class="identifier">success</span></code>
2615 and <code class="computeroutput"><span class="identifier">va</span></code> contains
2616 the dequeued value.
2617 </p></dd>
2618<dt><span class="term">Throws:</span></dt>
2619<dd><p>
2620 Exceptions thrown by copy- or move-operations.
2621 </p></dd>
2622</dl>
2623</div>
2624<p>
2625 </p>
2626<h5>
2627<a name="unbounded_channel_pop_wait_for_bridgehead"></a>
2628 <span><a name="unbounded_channel_pop_wait_for"></a></span>
2629 <a class="link" href="pooled_fixedsize.html#unbounded_channel_pop_wait_for">Member
2630 function <code class="computeroutput">pop_wait_for</code>()</a>
2631</h5>
2632<p>
2633 </p>
2634<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2635<span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_for</span><span class="special">(</span>
2636 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2637 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span>
2638</pre>
2639<div class="variablelist">
2640<p class="title"><b></b></p>
2641<dl>
2642<dt><span class="term">Effects:</span></dt>
2643<dd><p>
2644 Accepts <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span></code> and internally computes
2645 a timeout time as (system time + <code class="computeroutput"><span class="identifier">timeout_duration</span></code>).
2646 If channel is not empty, immediately dequeues a value from the
2647 channel. Otherwise the fiber gets suspended until at least one
2648 new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed (return value <code class="computeroutput"><span class="identifier">success</span></code> and <code class="computeroutput"><span class="identifier">va</span></code>
2649 contains dequeued value), or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
2650 reaches the computed timeout time (return value <code class="computeroutput"><span class="identifier">timeout</span></code>).
2651 </p></dd>
2652<dt><span class="term">Throws:</span></dt>
2653<dd><p>
2654 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2655 or timeout-related exceptions.
2656 </p></dd>
2657</dl>
2658</div>
2659<p>
2660 </p>
2661<h5>
2662<a name="unbounded_channel_pop_wait_until_bridgehead"></a>
2663 <span><a name="unbounded_channel_pop_wait_until"></a></span>
2664 <a class="link" href="pooled_fixedsize.html#unbounded_channel_pop_wait_until">Member
2665 function <code class="computeroutput">pop_wait_until</code>()</a>
2666</h5>
2667<p>
2668 </p>
2669<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2670<span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_until</span><span class="special">(</span>
2671 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2672 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span>
2673</pre>
2674<div class="variablelist">
2675<p class="title"><b></b></p>
2676<dl>
2677<dt><span class="term">Effects:</span></dt>
2678<dd><p>
2679 Accepts a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span>
2680 <span class="special">&gt;</span></code>. If channel is not
2681 empty, immediately dequeues a value from the channel. Otherwise
2682 the fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
2683 (return value <code class="computeroutput"><span class="identifier">success</span></code>
2684 and <code class="computeroutput"><span class="identifier">va</span></code> contains
2685 dequeued value), or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
2686 reaches the passed <code class="computeroutput"><span class="identifier">time_point</span></code>
2687 (return value <code class="computeroutput"><span class="identifier">timeout</span></code>).
2688 </p></dd>
2689<dt><span class="term">Throws:</span></dt>
2690<dd><p>
2691 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2692 or timeout-related exceptions.
2693 </p></dd>
2694</dl>
2695</div>
2696<p>
2697 </p>
2698<h5>
2699<a name="class_bounded_channel_bridgehead"></a>
2700 <span><a name="class_bounded_channel"></a></span>
2701 <a class="link" href="pooled_fixedsize.html#class_bounded_channel">Template
2702 <code class="computeroutput">bounded_channel&lt;&gt;</code></a>
2703</h5>
2704<p>
2705 </p>
2706<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">bounded_channel</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
2707
2708<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">=</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span></code></a> <span class="special">&gt;</span>
2709<span class="keyword">class</span> <span class="identifier">bounded_channel</span> <span class="special">{</span>
2710<span class="keyword">public</span><span class="special">:</span>
2711 <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">value_type</span><span class="special">;</span>
2712
2713 <span class="identifier">bounded_channel</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">wm</span><span class="special">,</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">);</span>
2714 <span class="identifier">bounded_channel</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">hwm</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lwm</span><span class="special">,</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">);</span>
2715
2716 <span class="identifier">bounded_channel</span><span class="special">(</span> <span class="identifier">bounded_channel</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2717 <span class="identifier">bounded_channel</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">bounded_channel</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
2718
2719 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">upper_bound</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
2720 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lower_bound</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
2721
2722 <span class="keyword">void</span> <span class="identifier">close</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
2723
2724 <span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2725 <span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2726 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2727 <span class="identifier">channel_op_status</span> <span class="identifier">push_wait_for</span><span class="special">(</span>
2728 <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2729 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2730 <span class="identifier">channel_op_status</span> <span class="identifier">push_wait_for</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2731 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2732 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2733 <span class="identifier">channel_op_status</span> <span class="identifier">push_wait_until</span><span class="special">(</span>
2734 <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2735 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2736 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2737 <span class="identifier">channel_op_status</span> <span class="identifier">push_wait_until</span><span class="special">(</span>
2738 <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2739 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2740 <span class="identifier">channel_op_status</span> <span class="identifier">try_push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2741 <span class="identifier">channel_op_status</span> <span class="identifier">try_push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2742
2743 <span class="identifier">channel_op_status</span> <span class="identifier">pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2744 <span class="identifier">value_type</span> <span class="identifier">value_pop</span><span class="special">();</span>
2745 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2746 <span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_for</span><span class="special">(</span>
2747 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2748 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2749 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2750 <span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_until</span><span class="special">(</span>
2751 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2752 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2753 <span class="identifier">channel_op_status</span> <span class="identifier">try_pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2754<span class="special">};</span>
2755</pre>
2756<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.h7"></a>
2757 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.constructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.channels.constructor0">Constructor</a>
2758 </h7><pre class="programlisting"><span class="identifier">bounded_channel</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">wm</span><span class="special">,</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">);</span>
2759<span class="identifier">bounded_channel</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">hwm</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lwm</span><span class="special">,</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span> <span class="special">=</span> <span class="identifier">Allocator</span><span class="special">()</span> <span class="special">);</span>
2760</pre>
2761<div class="variablelist">
2762<p class="title"><b></b></p>
2763<dl>
2764<dt><span class="term">Preconditions:</span></dt>
2765<dd><p>
2766 <code class="computeroutput"><span class="identifier">hwm</span> <span class="special">&gt;</span>
2767 <span class="identifier">lwm</span></code>
2768 </p></dd>
2769<dt><span class="term">Effects:</span></dt>
2770<dd><p>
2771 Constructs an object of class <code class="computeroutput"><span class="identifier">bounded_channel</span></code>.
2772 The constructor with two arguments constructs an object of class
2773 <code class="computeroutput"><span class="identifier">bounded_channel</span></code>
2774 with a high-watermark of <code class="computeroutput"><span class="identifier">hwm</span></code>
2775 and a low-watermark of <code class="computeroutput"><span class="identifier">lwm</span></code>
2776 items. The constructor with one <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span></code>
2777 argument is effectively the same as <code class="computeroutput"><span class="identifier">bounded_channel</span><span class="special">(</span><span class="identifier">wm</span><span class="special">,</span> <span class="special">(</span><span class="identifier">wm</span><span class="special">-</span><span class="number">1</span><span class="special">),</span> <span class="identifier">alloc</span><span class="special">)</span></code>.
2778 Internal nodes are allocated using <code class="computeroutput"><span class="identifier">alloc</span></code>
2779 - C++11-allocators are supported.
2780 </p></dd>
2781<dt><span class="term">Throws:</span></dt>
2782<dd><p>
2783 <code class="computeroutput"><span class="identifier">fiber_error</span></code>
2784 </p></dd>
2785<dt><span class="term">Error Conditions:</span></dt>
2786<dd><p>
2787 <span class="bold"><strong>invalid_argument</strong></span>: if <code class="computeroutput"><span class="identifier">lwm</span> <span class="special">&gt;=</span>
2788 <span class="identifier">hwm</span></code>.
2789 </p></dd>
2790<dt><span class="term">Notes:</span></dt>
2791<dd><p>
2792 Once the number of values in the channel reaches <code class="computeroutput"><span class="identifier">hwm</span></code>, any call to <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>,
2793 <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> will block until the number
2794 of values in the channel is at most <code class="computeroutput"><span class="identifier">lwm</span></code>.
2795 That is, if <code class="computeroutput"><span class="identifier">lwm</span> <span class="special">&lt;</span> <span class="special">(</span><span class="identifier">hwm</span><span class="special">-</span><span class="number">1</span><span class="special">)</span></code>,
2796 the channel can be in a state in which <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> calls will block (channel is
2797 full) even though the number of values in the channel is less
2798 than <code class="computeroutput"><span class="identifier">hwm</span></code>.
2799 </p></dd>
2800<dt><span class="term">See also:</span></dt>
2801<dd><p>
2802 <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> concept,
2803 <a href="http://en.cppreference.com/w/cpp/memory/allocator" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator</span><span class="special">&lt;</span>
2804 <span class="identifier">T</span> <span class="special">&gt;</span></code></a>
2805 </p></dd>
2806</dl>
2807</div>
2808<p>
2809 </p>
2810<h5>
2811<a name="bounded_channel_upper_bound_bridgehead"></a>
2812 <span><a name="bounded_channel_upper_bound"></a></span>
2813 <a class="link" href="pooled_fixedsize.html#bounded_channel_upper_bound">Member
2814 function <code class="computeroutput">upper_bound</code>()</a>
2815</h5>
2816<p>
2817 </p>
2818<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">upper_bound</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
2819</pre>
2820<div class="variablelist">
2821<p class="title"><b></b></p>
2822<dl>
2823<dt><span class="term">Returns:</span></dt>
2824<dd><p>
2825 the high-watermark with which <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> was constructed.
2826 </p></dd>
2827<dt><span class="term">Throws:</span></dt>
2828<dd><p>
2829 Nothing.
2830 </p></dd>
2831</dl>
2832</div>
2833<p>
2834 </p>
2835<h5>
2836<a name="bounded_channel_lower_bound_bridgehead"></a>
2837 <span><a name="bounded_channel_lower_bound"></a></span>
2838 <a class="link" href="pooled_fixedsize.html#bounded_channel_lower_bound">Member
2839 function <code class="computeroutput">lower_bound</code>()</a>
2840</h5>
2841<p>
2842 </p>
2843<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lower_bound</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
2844</pre>
2845<div class="variablelist">
2846<p class="title"><b></b></p>
2847<dl>
2848<dt><span class="term">Returns:</span></dt>
2849<dd><p>
2850 the low-watermark with which <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> was constructed.
2851 </p></dd>
2852<dt><span class="term">Throws:</span></dt>
2853<dd><p>
2854 Nothing.
2855 </p></dd>
2856</dl>
2857</div>
2858<p>
2859 </p>
2860<h5>
2861<a name="bounded_channel_close_bridgehead"></a>
2862 <span><a name="bounded_channel_close"></a></span>
2863 <a class="link" href="pooled_fixedsize.html#bounded_channel_close">Member
2864 function <code class="computeroutput">close</code>()</a>
2865</h5>
2866<p>
2867 </p>
2868<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">close</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
2869</pre>
2870<div class="variablelist">
2871<p class="title"><b></b></p>
2872<dl>
2873<dt><span class="term">Effects:</span></dt>
2874<dd><p>
2875 Deactivates the channel. No values can be put after calling
2876 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">()</span></code>.
2877 Fibers blocked in <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> will return <code class="computeroutput"><span class="identifier">closed</span></code>.
2878 Fibers blocked in <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code> will receive an exception.
2879 </p></dd>
2880<dt><span class="term">Throws:</span></dt>
2881<dd><p>
2882 Nothing.
2883 </p></dd>
2884<dt><span class="term">Note:</span></dt>
2885<dd><p>
2886 <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>
2887 is like closing a pipe. It informs waiting consumers that no
2888 more values will arrive.
2889 </p></dd>
2890</dl>
2891</div>
2892<p>
2893 </p>
2894<h5>
2895<a name="bounded_channel_push_bridgehead"></a>
2896 <span><a name="bounded_channel_push"></a></span>
2897 <a class="link" href="pooled_fixedsize.html#bounded_channel_push">Member
2898 function <code class="computeroutput">push</code>()</a>
2899</h5>
2900<p>
2901 </p>
2902<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2903<span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
2904</pre>
2905<div class="variablelist">
2906<p class="title"><b></b></p>
2907<dl>
2908<dt><span class="term">Effects:</span></dt>
2909<dd><p>
2910 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
2911 If channel is not full, enqueues the value in the channel, wakes
2912 up a fiber blocked on <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> and returns <code class="computeroutput"><span class="identifier">success</span></code>.
2913 Otherwise the calling fiber is suspended until the number of
2914 values in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>
2915 (return value <code class="computeroutput"><span class="identifier">success</span></code>)or
2916 the channel is <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>).
2917 </p></dd>
2918<dt><span class="term">Throws:</span></dt>
2919<dd><p>
2920 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
2921 or exceptions thrown by memory allocation and copying or moving
2922 <code class="computeroutput"><span class="identifier">va</span></code>.
2923 </p></dd>
2924</dl>
2925</div>
2926<p>
2927 </p>
2928<h5>
2929<a name="bounded_channel_push_wait_for_bridgehead"></a>
2930 <span><a name="bounded_channel_push_wait_for"></a></span>
2931 <a class="link" href="pooled_fixedsize.html#bounded_channel_push_wait_for">Member
2932 function <code class="computeroutput">push_wait_for</code>()</a>
2933</h5>
2934<p>
2935 </p>
2936<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2937<span class="identifier">channel_op_status</span> <span class="identifier">push_wait_for</span><span class="special">(</span>
2938 <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2939 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2940
2941<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
2942<span class="identifier">channel_op_status</span> <span class="identifier">push_wait_for</span><span class="special">(</span>
2943 <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2944 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">);</span>
2945</pre>
2946<div class="variablelist">
2947<p class="title"><b></b></p>
2948<dl>
2949<dt><span class="term">Effects:</span></dt>
2950<dd><p>
2951 Accepts <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span></code> and internally computes
2952 a time_point as (system time + <code class="computeroutput"><span class="identifier">timeout_duration</span></code>).
2953 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
2954 If channel is not full, enqueues the value in the channel, wakes
2955 up a fiber blocked on <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> and returns <code class="computeroutput"><span class="identifier">success</span></code>.
2956 Otherwise the calling fiber is suspended until the number of
2957 values in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>
2958 (return value <code class="computeroutput"><span class="identifier">success</span></code>),
2959 the channel is <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
2960 reaches the computed time_point (return value <code class="computeroutput"><span class="identifier">timeout</span></code>).
2961 </p></dd>
2962<dt><span class="term">Throws:</span></dt>
2963<dd><p>
2964 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>,
2965 exceptions thrown by memory allocation and copying or moving
2966 <code class="computeroutput"><span class="identifier">va</span></code> or timeout-related
2967 exceptions.
2968 </p></dd>
2969</dl>
2970</div>
2971<p>
2972 </p>
2973<h5>
2974<a name="bounded_channel_push_wait_until_bridgehead"></a>
2975 <span><a name="bounded_channel_push_wait_until"></a></span>
2976 <a class="link" href="pooled_fixedsize.html#bounded_channel_push_wait_until">Member
2977 function <code class="computeroutput">push_wait_until</code>()</a>
2978</h5>
2979<p>
2980 </p>
2981<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2982<span class="identifier">channel_op_status</span> <span class="identifier">push_wait_until</span><span class="special">(</span>
2983 <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2984 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2985
2986<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
2987<span class="identifier">channel_op_status</span> <span class="identifier">push_wait_until</span><span class="special">(</span>
2988 <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">,</span>
2989 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">);</span>
2990</pre>
2991<div class="variablelist">
2992<p class="title"><b></b></p>
2993<dl>
2994<dt><span class="term">Effects:</span></dt>
2995<dd><p>
2996 Accepts an absolute <code class="computeroutput"><span class="identifier">timeout_time</span></code>
2997 in any supported time_point type. If channel is closed, returns
2998 <code class="computeroutput"><span class="identifier">closed</span></code>. If channel
2999 is not full, enqueues the value in the channel, wakes up a fiber
3000 blocked on <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> and returns <code class="computeroutput"><span class="identifier">success</span></code>.
3001 Otherwise the calling fiber is suspended until the number of
3002 values in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>
3003 (return value <code class="computeroutput"><span class="identifier">success</span></code>),
3004 the channel is <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
3005 reaches the passed time_point (return value <code class="computeroutput"><span class="identifier">timeout</span></code>).
3006 </p></dd>
3007<dt><span class="term">Throws:</span></dt>
3008<dd><p>
3009 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3010 or exceptions thrown by memory allocation and copying or moving
3011 <code class="computeroutput"><span class="identifier">va</span></code> or timeout-related
3012 exceptions.
3013 </p></dd>
3014</dl>
3015</div>
3016<p>
3017 </p>
3018<h5>
3019<a name="bounded_channel_try_push_bridgehead"></a>
3020 <span><a name="bounded_channel_try_push"></a></span>
3021 <a class="link" href="pooled_fixedsize.html#bounded_channel_try_push">Member
3022 function <code class="computeroutput">try_push</code>()</a>
3023</h5>
3024<p>
3025 </p>
3026<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">try_push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
3027<span class="identifier">channel_op_status</span> <span class="identifier">try_push</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">);</span>
3028</pre>
3029<div class="variablelist">
3030<p class="title"><b></b></p>
3031<dl>
3032<dt><span class="term">Effects:</span></dt>
3033<dd><p>
3034 If channel is full, returns <code class="computeroutput"><span class="identifier">full</span></code>.
3035 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
3036 Otherwise enqueues the value in the channel, wakes up a fiber
3037 blocked on <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span></code>, <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">pop_wait_until</span><span class="special">()</span></code> and returns <code class="computeroutput"><span class="identifier">success</span></code>.
3038 </p></dd>
3039<dt><span class="term">Throws:</span></dt>
3040<dd><p>
3041 Exceptions thrown by memory allocation and copying or moving
3042 <code class="computeroutput"><span class="identifier">va</span></code>.
3043 </p></dd>
3044</dl>
3045</div>
3046<p>
3047 </p>
3048<h5>
3049<a name="bounded_channel_pop_bridgehead"></a>
3050 <span><a name="bounded_channel_pop"></a></span>
3051 <a class="link" href="pooled_fixedsize.html#bounded_channel_pop">Member
3052 function <code class="computeroutput">pop</code>()</a>
3053</h5>
3054<p>
3055 </p>
3056<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
3057</pre>
3058<div class="variablelist">
3059<p class="title"><b></b></p>
3060<dl>
3061<dt><span class="term">Effects:</span></dt>
3062<dd><p>
3063 Dequeues a value from the channel. If the channel is empty, the
3064 fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
3065 (return value <code class="computeroutput"><span class="identifier">success</span></code>
3066 and <code class="computeroutput"><span class="identifier">va</span></code> contains
3067 dequeued value) or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>). Once the number of
3068 items remaining in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>,
3069 any fibers blocked on <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> may resume.
3070 </p></dd>
3071<dt><span class="term">Throws:</span></dt>
3072<dd><p>
3073 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3074 </p></dd>
3075</dl>
3076</div>
3077<p>
3078 </p>
3079<h5>
3080<a name="bounded_channel_value_pop_bridgehead"></a>
3081 <span><a name="bounded_channel_value_pop"></a></span>
3082 <a class="link" href="pooled_fixedsize.html#bounded_channel_value_pop">Member
3083 function <code class="computeroutput">value_pop</code>()</a>
3084</h5>
3085<p>
3086 </p>
3087<pre class="programlisting"><span class="identifier">value_type</span> <span class="identifier">value_pop</span><span class="special">();</span>
3088</pre>
3089<div class="variablelist">
3090<p class="title"><b></b></p>
3091<dl>
3092<dt><span class="term">Effects:</span></dt>
3093<dd><p>
3094 Dequeues a value from the channel. If the channel is empty, the
3095 fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
3096 or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (which throws an exception).
3097 Once the number of items remaining in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>, any fibers blocked on
3098 <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>,
3099 <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> may resume.
3100 </p></dd>
3101<dt><span class="term">Throws:</span></dt>
3102<dd><p>
3103 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
3104 <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
3105 is closed or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3106 </p></dd>
3107<dt><span class="term">Error conditions:</span></dt>
3108<dd><p>
3109 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">errc</span><span class="special">::</span><span class="identifier">operation_not_permitted</span></code>
3110 </p></dd>
3111</dl>
3112</div>
3113<p>
3114 </p>
3115<h5>
3116<a name="bounded_channel_try_pop_bridgehead"></a>
3117 <span><a name="bounded_channel_try_pop"></a></span>
3118 <a class="link" href="pooled_fixedsize.html#bounded_channel_try_pop">Member
3119 function <code class="computeroutput">try_pop</code>()</a>
3120</h5>
3121<p>
3122 </p>
3123<pre class="programlisting"><span class="identifier">channel_op_status</span> <span class="identifier">try_pop</span><span class="special">(</span> <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">);</span>
3124</pre>
3125<div class="variablelist">
3126<p class="title"><b></b></p>
3127<dl>
3128<dt><span class="term">Effects:</span></dt>
3129<dd><p>
3130 If channel is empty, returns <code class="computeroutput"><span class="identifier">empty</span></code>.
3131 If channel is closed, returns <code class="computeroutput"><span class="identifier">closed</span></code>.
3132 Otherwise it returns <code class="computeroutput"><span class="identifier">success</span></code>
3133 and <code class="computeroutput"><span class="identifier">va</span></code> contains
3134 the dequeued value. Once the number of items remaining in the
3135 channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>,
3136 any fibers blocked on <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> may resume.
3137 </p></dd>
3138<dt><span class="term">Throws:</span></dt>
3139<dd><p>
3140 Exceptions thrown by copy- or move-operations.
3141 </p></dd>
3142</dl>
3143</div>
3144<p>
3145 </p>
3146<h5>
3147<a name="bounded_channel_pop_wait_for_bridgehead"></a>
3148 <span><a name="bounded_channel_pop_wait_for"></a></span>
3149 <a class="link" href="pooled_fixedsize.html#bounded_channel_pop_wait_for">Member
3150 function <code class="computeroutput">pop_wait_for</code>()</a>
3151</h5>
3152<p>
3153 </p>
3154<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
3155<span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_for</span><span class="special">(</span>
3156 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
3157 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span>
3158</pre>
3159<div class="variablelist">
3160<p class="title"><b></b></p>
3161<dl>
3162<dt><span class="term">Effects:</span></dt>
3163<dd><p>
3164 Accepts <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span></code> and internally computes
3165 a timeout time as (system time + <code class="computeroutput"><span class="identifier">timeout_duration</span></code>).
3166 If channel is not empty, immediately dequeues a value from the
3167 channel. Otherwise the fiber gets suspended until at least one
3168 new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed (return value <code class="computeroutput"><span class="identifier">success</span></code> and <code class="computeroutput"><span class="identifier">va</span></code>
3169 contains dequeued value), or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
3170 reaches the computed timeout time (return value <code class="computeroutput"><span class="identifier">timeout</span></code>). Once the number of
3171 items remaining in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>,
3172 any fibers blocked on <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>, <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> may resume.
3173 </p></dd>
3174<dt><span class="term">Throws:</span></dt>
3175<dd><p>
3176 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3177 or timeout-related exceptions.
3178 </p></dd>
3179</dl>
3180</div>
3181<p>
3182 </p>
3183<h5>
3184<a name="bounded_channel_pop_wait_until_bridgehead"></a>
3185 <span><a name="bounded_channel_pop_wait_until"></a></span>
3186 <a class="link" href="pooled_fixedsize.html#bounded_channel_pop_wait_until">Member
3187 function <code class="computeroutput">pop_wait_until</code>()</a>
3188</h5>
3189<p>
3190 </p>
3191<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
3192<span class="identifier">channel_op_status</span> <span class="identifier">pop_wait_until</span><span class="special">(</span>
3193 <span class="identifier">value_type</span> <span class="special">&amp;</span> <span class="identifier">va</span><span class="special">,</span>
3194 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span>
3195</pre>
3196<div class="variablelist">
3197<p class="title"><b></b></p>
3198<dl>
3199<dt><span class="term">Effects:</span></dt>
3200<dd><p>
3201 Accepts a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span>
3202 <span class="special">&gt;</span></code>. If channel is not
3203 empty, immediately dequeues a value from the channel. Otherwise
3204 the fiber gets suspended until at least one new item is <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>ed
3205 (return value <code class="computeroutput"><span class="identifier">success</span></code>
3206 and <code class="computeroutput"><span class="identifier">va</span></code> contains
3207 dequeued value), or the channel gets <code class="computeroutput"><span class="identifier">close</span><span class="special">()</span></code>d (return value <code class="computeroutput"><span class="identifier">closed</span></code>), or the system time
3208 reaches the passed <code class="computeroutput"><span class="identifier">time_point</span></code>
3209 (return value <code class="computeroutput"><span class="identifier">timeout</span></code>).
3210 Once the number of items remaining in the channel drops to <code class="computeroutput"><span class="identifier">lwm</span></code>, any fibers blocked on
3211 <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>,
3212 <code class="computeroutput"><span class="identifier">push_wait_for</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">push_wait_until</span><span class="special">()</span></code> may resume.
3213 </p></dd>
3214<dt><span class="term">Throws:</span></dt>
3215<dd><p>
3216 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3217 or timeout-related exceptions.
3218 </p></dd>
3219</dl>
3220</div>
3221</div>
3222<div class="section">
3223<div class="titlepage"><div><div><h6 class="title">
3224<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures" title="Futures">Futures</a>
3225</h6></div></div></div>
3226<div class="toc"><dl>
3227<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future">Future</a></span></dt>
3228<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise">Template
3229 <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code></a></span></dt>
3230<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task">Template
3231 <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code></a></span></dt>
3232</dl></div>
3233<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.h0"></a>
3234 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.overview">Overview</a>
3235 </h7><p>
3236 The futures library provides a means of handling asynchronous future
3237 values, whether those values are generated by another fiber, or on
3238 a single fiber in response to external stimuli, or on-demand.
3239 </p>
3240<p>
3241 This is done through the provision of four class templates: <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> and
3242 <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> which are used to retrieve
3243 the asynchronous results, and <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> and <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> which
3244 are used to generate the asynchronous results.
3245 </p>
3246<p>
3247 An instance of <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> holds the one and only reference
3248 to a result. Ownership can be transferred between instances using the
3249 move constructor or move-assignment operator, but at most one instance
3250 holds a reference to a given asynchronous result. When the result is
3251 ready, it is returned from <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> by rvalue-reference
3252 to allow the result to be moved or copied as appropriate for the type.
3253 </p>
3254<p>
3255 On the other hand, many instances of <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> may
3256 reference the same result. Instances can be freely copied and assigned,
3257 and <a class="link" href="pooled_fixedsize.html#shared_future_get"> <code class="computeroutput">shared_future::get()</code></a>
3258returns a <code class="computeroutput"><span class="keyword">const</span></code>
3259 reference so that multiple calls to <a class="link" href="pooled_fixedsize.html#shared_future_get"> <code class="computeroutput">shared_future::get()</code></a>
3260are
3261 safe. You can move an instance of <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> into an
3262 instance of <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a>, thus transferring
3263 ownership of the associated asynchronous result, but not vice-versa.
3264 </p>
3265<p>
3266 <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a> is a simple way of running asynchronous
3267 tasks. A call to <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code> spawns a fiber and returns a <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> that
3268 will deliver the result of the fiber function.
3269 </p>
3270<h7><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.h1"></a>
3271 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.creating_asynchronous_values"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.creating_asynchronous_values">Creating
3272 asynchronous values</a>
3273 </h7><p>
3274 You can set the value in a future with either a <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> or
3275 a <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a>. A <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> is
3276 a callable object with <code class="computeroutput"><span class="keyword">void</span></code>
3277 return that wraps a function or callable object returning the specified
3278 type. When the <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> is invoked,
3279 it invokes the contained function in turn, and populates a future with
3280 the contained function's return value. This is an answer to the perennial
3281 question: <span class="quote">&#8220;<span class="quote">How do I return a value from a fiber?</span>&#8221;</span> Package
3282 the function you wish to run as a <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> and
3283 pass the packaged task to the fiber constructor. The future retrieved
3284 from the packaged task can then be used to obtain the return value.
3285 If the function throws an exception, that is stored in the future in
3286 place of the return value.
3287 </p>
3288<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">calculate_the_answer_to_life_the_universe_and_everything</span><span class="special">()</span> <span class="special">{</span>
3289 <span class="keyword">return</span> <span class="number">42</span><span class="special">;</span>
3290<span class="special">}</span>
3291
3292<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">()&gt;</span> <span class="identifier">pt</span><span class="special">(</span><span class="identifier">calculate_the_answer_to_life_the_universe_and_everything</span><span class="special">);</span>
3293<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fi</span><span class="special">=</span><span class="identifier">pt</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">();</span>
3294<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">pt</span><span class="special">)).</span><span class="identifier">detach</span><span class="special">();</span> <span class="comment">// launch task on a fiber</span>
3295
3296<span class="identifier">fi</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span> <span class="comment">// wait for it to finish</span>
3297
3298<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">is_ready</span><span class="special">());</span>
3299<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_value</span><span class="special">());</span>
3300<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_exception</span><span class="special">());</span>
3301<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">get</span><span class="special">()==</span><span class="number">42</span><span class="special">);</span>
3302</pre>
3303<p>
3304 A <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> is a bit more low level: it just provides
3305 explicit functions to store a value or an exception in the associated
3306 future. A promise can therefore be used where the value might come
3307 from more than one possible source.
3308 </p>
3309<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">pi</span><span class="special">;</span>
3310<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">fi</span><span class="special">;</span>
3311<span class="identifier">fi</span><span class="special">=</span><span class="identifier">pi</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">();</span>
3312
3313<span class="identifier">pi</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span><span class="number">42</span><span class="special">);</span>
3314
3315<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">is_ready</span><span class="special">());</span>
3316<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_value</span><span class="special">());</span>
3317<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">has_exception</span><span class="special">());</span>
3318<span class="identifier">assert</span><span class="special">(</span><span class="identifier">fi</span><span class="special">.</span><span class="identifier">get</span><span class="special">()==</span><span class="number">42</span><span class="special">);</span>
3319</pre>
3320<div class="section">
3321<div class="titlepage"><div><div><h6 class="title">
3322<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future" title="Future">Future</a>
3323</h6></div></div></div>
3324<p>
3325 A future provides a mechanism to access the result of an asynchronous
3326 operation.
3327 </p>
3328<a name="shared_state"></a><h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h0"></a>
3329 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.shared_state"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.shared_state">shared
3330 state</a>
3331 </h8><p>
3332 Behind a <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> and its <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> lies
3333 an unspecified object called their <span class="emphasis"><em>shared state</em></span>.
3334 The shared state is what will actually hold the async result (or
3335 the exception).
3336 </p>
3337<p>
3338 The shared state is instantiated along with the <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a>.
3339 </p>
3340<p>
3341 Aside from its originating <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code>, a <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> holds
3342 a unique reference to a particular shared state. However, multiple
3343 <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> instances can reference the
3344 same underlying shared state.
3345 </p>
3346<p>
3347 As <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> and <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a> are
3348 implemented using <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a>, discussions of shared
3349 state apply to them as well.
3350 </p>
3351<a name="class_future_status"></a><h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h1"></a>
3352 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.enumeration__code__phrase_role__identifier__future_status__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.enumeration__code__phrase_role__identifier__future_status__phrase___code_">Enumeration
3353 <code class="computeroutput"><span class="identifier">future_status</span></code></a>
3354 </h8><p>
3355 Timed wait-operations ( <a class="link" href="pooled_fixedsize.html#future_wait_for"> <code class="computeroutput">future::wait_for()</code></a> and <a class="link" href="pooled_fixedsize.html#future_wait_until"> <code class="computeroutput">future::wait_until()</code></a>)
3356 return the state of the future.
3357 </p>
3358<pre class="programlisting"><span class="keyword">enum</span> <span class="keyword">class</span> <span class="identifier">future_status</span> <span class="special">{</span>
3359 <span class="identifier">ready</span><span class="special">,</span>
3360 <span class="identifier">timeout</span><span class="special">,</span>
3361 <span class="identifier">deferred</span> <span class="comment">// not supported yet</span>
3362<span class="special">};</span>
3363</pre>
3364<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h2"></a>
3365 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future._code__phrase_role__identifier__ready__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future._code__phrase_role__identifier__ready__phrase___code_"><code class="computeroutput"><span class="identifier">ready</span></code></a>
3366 </h8><div class="variablelist">
3367<p class="title"><b></b></p>
3368<dl>
3369<dt><span class="term">Effects:</span></dt>
3370<dd><p>
3371 The <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a> is ready.
3372 </p></dd>
3373</dl>
3374</div>
3375<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h3"></a>
3376 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future._code__phrase_role__identifier__timeout__phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future._code__phrase_role__identifier__timeout__phrase___code_"><code class="computeroutput"><span class="identifier">timeout</span></code></a>
3377 </h8><div class="variablelist">
3378<p class="title"><b></b></p>
3379<dl>
3380<dt><span class="term">Effects:</span></dt>
3381<dd><p>
3382 The <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a> did not
3383 become ready before timeout has passed.
3384 </p></dd>
3385</dl>
3386</div>
3387<div class="note"><table border="0" summary="Note">
3388<tr>
3389<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
3390<th align="left">Note</th>
3391</tr>
3392<tr><td align="left" valign="top"><p>
3393 Deferred futures are not supported.
3394 </p></td></tr>
3395</table></div>
3396<p>
3397 </p>
3398<h5>
3399<a name="class_future_bridgehead"></a>
3400 <span><a name="class_future"></a></span>
3401 <a class="link" href="pooled_fixedsize.html#class_future">Template <code class="computeroutput">future&lt;&gt;</code></a>
3402</h5>
3403<p>
3404 </p>
3405<p>
3406 A <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> contains a <a class="link" href="pooled_fixedsize.html#shared_state">shared
3407 state</a> which is not shared with any other future.
3408 </p>
3409<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">R</span> <span class="special">&gt;</span>
3410<span class="keyword">class</span> <span class="identifier">future</span> <span class="special">{</span>
3411<span class="keyword">public</span><span class="special">:</span>
3412 <span class="identifier">future</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
3413
3414 <span class="identifier">future</span><span class="special">(</span> <span class="identifier">future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
3415
3416 <span class="identifier">future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
3417
3418 <span class="identifier">future</span><span class="special">(</span> <span class="identifier">future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3419
3420 <span class="identifier">future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3421
3422 <span class="special">~</span><span class="identifier">future</span><span class="special">();</span>
3423
3424 <span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
3425
3426 <span class="identifier">shared_future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">share</span><span class="special">();</span>
3427
3428 <span class="identifier">R</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of generic future template</span>
3429 <span class="identifier">R</span> <span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of future&lt; R &amp; &gt; template specialization</span>
3430 <span class="keyword">void</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of future&lt; void &gt; template specialization</span>
3431
3432 <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">get_exception_ptr</span><span class="special">();</span>
3433
3434 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
3435
3436 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
3437 <span class="identifier">future_status</span> <span class="identifier">wait_for</span><span class="special">(</span>
3438 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3439
3440 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
3441 <span class="identifier">future_status</span> <span class="identifier">wait_until</span><span class="special">(</span>
3442 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3443<span class="special">};</span>
3444</pre>
3445<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h4"></a>
3446 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.default_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.default_constructor">Default
3447 constructor</a>
3448 </h8><pre class="programlisting"><span class="identifier">future</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
3449</pre>
3450<div class="variablelist">
3451<p class="title"><b></b></p>
3452<dl>
3453<dt><span class="term">Effects:</span></dt>
3454<dd><p>
3455 Creates a future with no <a class="link" href="pooled_fixedsize.html#shared_state">shared
3456 state</a>. After construction <code class="computeroutput"><span class="keyword">false</span>
3457 <span class="special">==</span> <span class="identifier">valid</span><span class="special">()</span></code>.
3458 </p></dd>
3459<dt><span class="term">Throws:</span></dt>
3460<dd><p>
3461 Nothing.
3462 </p></dd>
3463</dl>
3464</div>
3465<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h5"></a>
3466 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.move_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.move_constructor">Move
3467 constructor</a>
3468 </h8><pre class="programlisting"><span class="identifier">future</span><span class="special">(</span> <span class="identifier">future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3469</pre>
3470<div class="variablelist">
3471<p class="title"><b></b></p>
3472<dl>
3473<dt><span class="term">Effects:</span></dt>
3474<dd><p>
3475 Constructs a future with the <a class="link" href="pooled_fixedsize.html#shared_state">shared
3476 state</a> of other. After construction <code class="computeroutput"><span class="keyword">false</span>
3477 <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">valid</span><span class="special">()</span></code>.
3478 </p></dd>
3479<dt><span class="term">Throws:</span></dt>
3480<dd><p>
3481 Nothing.
3482 </p></dd>
3483</dl>
3484</div>
3485<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h6"></a>
3486 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.destructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.destructor">Destructor</a>
3487 </h8><pre class="programlisting"><span class="special">~</span><span class="identifier">future</span><span class="special">();</span>
3488</pre>
3489<div class="variablelist">
3490<p class="title"><b></b></p>
3491<dl>
3492<dt><span class="term">Effects:</span></dt>
3493<dd><p>
3494 Destroys the future; ownership is abandoned.
3495 </p></dd>
3496<dt><span class="term">Note:</span></dt>
3497<dd><p>
3498 <code class="computeroutput">~future()</code> does <span class="emphasis"><em>not</em></span> block the calling fiber.
3499 </p></dd>
3500</dl>
3501</div>
3502<p>
3503 Consider a sequence such as:
3504 </p>
3505<div class="orderedlist"><ol class="orderedlist" type="1">
3506<li class="listitem">
3507 instantiate <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a>
3508 </li>
3509<li class="listitem">
3510 obtain its <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> via <a class="link" href="pooled_fixedsize.html#promise_get_future"> <code class="computeroutput">promise::get_future()</code></a>
3511 </li>
3512<li class="listitem">
3513 launch <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a>, capturing <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code>
3514 </li>
3515<li class="listitem">
3516 destroy <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
3517 </li>
3518<li class="listitem">
3519 call <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a>
3520 </li>
3521</ol></div>
3522<p>
3523 The final <code class="computeroutput"><span class="identifier">set_value</span><span class="special">()</span></code> call succeeds, but the value is
3524 silently discarded: no additional <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> can be obtained from that
3525 <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code>.
3526 </p>
3527<p>
3528 </p>
3529<h5>
3530<a name="future_operator_assign_bridgehead"></a>
3531 <span><a name="future_operator_assign"></a></span>
3532 <a class="link" href="pooled_fixedsize.html#future_operator_assign">Member
3533 function <code class="computeroutput">operator=</code>()</a>
3534</h5>
3535<p>
3536 </p>
3537<pre class="programlisting"><span class="identifier">future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3538</pre>
3539<div class="variablelist">
3540<p class="title"><b></b></p>
3541<dl>
3542<dt><span class="term">Effects:</span></dt>
3543<dd><p>
3544 Moves the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
3545 of other to <code class="computeroutput"><span class="keyword">this</span></code>.
3546 After the assignment, <code class="computeroutput"><span class="keyword">false</span>
3547 <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">valid</span><span class="special">()</span></code>.
3548 </p></dd>
3549<dt><span class="term">Throws:</span></dt>
3550<dd><p>
3551 Nothing.
3552 </p></dd>
3553</dl>
3554</div>
3555<p>
3556 </p>
3557<h5>
3558<a name="future_valid_bridgehead"></a>
3559 <span><a name="future_valid"></a></span>
3560 <a class="link" href="pooled_fixedsize.html#future_valid">Member function <code class="computeroutput">valid</code>()</a>
3561</h5>
3562<p>
3563 </p>
3564<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
3565</pre>
3566<div class="variablelist">
3567<p class="title"><b></b></p>
3568<dl>
3569<dt><span class="term">Effects:</span></dt>
3570<dd><p>
3571 Returns <code class="computeroutput"><span class="keyword">true</span></code> if
3572 future contains a <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>.
3573 </p></dd>
3574<dt><span class="term">Throws:</span></dt>
3575<dd><p>
3576 Nothing.
3577 </p></dd>
3578</dl>
3579</div>
3580<p>
3581 </p>
3582<h5>
3583<a name="future_share_bridgehead"></a>
3584 <span><a name="future_share"></a></span>
3585 <a class="link" href="pooled_fixedsize.html#future_share">Member function <code class="computeroutput">share</code>()</a>
3586</h5>
3587<p>
3588 </p>
3589<pre class="programlisting"><span class="identifier">shared_future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">share</span><span class="special">();</span>
3590</pre>
3591<div class="variablelist">
3592<p class="title"><b></b></p>
3593<dl>
3594<dt><span class="term">Effects:</span></dt>
3595<dd><p>
3596 Move the state to a <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a>.
3597 </p></dd>
3598<dt><span class="term">Returns:</span></dt>
3599<dd><p>
3600 a <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> containing the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a> formerly belonging
3601 to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
3602 </p></dd>
3603<dt><span class="term">Postcondition:</span></dt>
3604<dd><p>
3605 <code class="computeroutput"><span class="keyword">false</span> <span class="special">==</span>
3606 <span class="identifier">valid</span><span class="special">()</span></code>
3607 </p></dd>
3608<dt><span class="term">Throws:</span></dt>
3609<dd><p>
3610 <code class="computeroutput"><span class="identifier">future_error</span></code>
3611 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
3612 </p></dd>
3613</dl>
3614</div>
3615<p>
3616 </p>
3617<h5>
3618<a name="future_get_bridgehead"></a>
3619 <span><a name="future_get"></a></span>
3620 <a class="link" href="pooled_fixedsize.html#future_get">Member function <code class="computeroutput">get</code>()</a>
3621</h5>
3622<p>
3623 </p>
3624<pre class="programlisting"><span class="identifier">R</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of generic future template</span>
3625<span class="identifier">R</span> <span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of future&lt; R &amp; &gt; template specialization</span>
3626<span class="keyword">void</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of future&lt; void &gt; template specialization</span>
3627</pre>
3628<div class="variablelist">
3629<p class="title"><b></b></p>
3630<dl>
3631<dt><span class="term">Precondition:</span></dt>
3632<dd><p>
3633 <code class="computeroutput"><span class="keyword">true</span> <span class="special">==</span>
3634 <span class="identifier">valid</span><span class="special">()</span></code>
3635 </p></dd>
3636<dt><span class="term">Returns:</span></dt>
3637<dd><p>
3638 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3639 called. If <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> is called,
3640 returns the value. If <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3641 called, throws the indicated exception.
3642 </p></dd>
3643<dt><span class="term">Postcondition:</span></dt>
3644<dd><p>
3645 <code class="computeroutput"><span class="keyword">false</span> <span class="special">==</span>
3646 <span class="identifier">valid</span><span class="special">()</span></code>
3647 </p></dd>
3648<dt><span class="term">Throws:</span></dt>
3649<dd><p>
3650 <code class="computeroutput"><span class="identifier">future_error</span></code>
3651 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>,
3652 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>,
3653 <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">broken_promise</span></code>.
3654 Any exception passed to <code class="computeroutput"><span class="identifier">promise</span><span class="special">::</span><span class="identifier">set_exception</span><span class="special">()</span></code>.
3655 </p></dd>
3656</dl>
3657</div>
3658<p>
3659 </p>
3660<h5>
3661<a name="future_get_exception_ptr_bridgehead"></a>
3662 <span><a name="future_get_exception_ptr"></a></span>
3663 <a class="link" href="pooled_fixedsize.html#future_get_exception_ptr">Member
3664 function <code class="computeroutput">get_exception_ptr</code>()</a>
3665</h5>
3666<p>
3667 </p>
3668<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">get_exception_ptr</span><span class="special">();</span>
3669</pre>
3670<div class="variablelist">
3671<p class="title"><b></b></p>
3672<dl>
3673<dt><span class="term">Precondition:</span></dt>
3674<dd><p>
3675 <code class="computeroutput"><span class="keyword">true</span> <span class="special">==</span>
3676 <span class="identifier">valid</span><span class="special">()</span></code>
3677 </p></dd>
3678<dt><span class="term">Returns:</span></dt>
3679<dd><p>
3680 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3681 called. If <code class="computeroutput"><span class="identifier">set_value</span><span class="special">()</span></code> is called, returns a default-constructed
3682 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>. If <code class="computeroutput"><span class="identifier">set_exception</span><span class="special">()</span></code>
3683 is called, returns the passed <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>.
3684 </p></dd>
3685<dt><span class="term">Throws:</span></dt>
3686<dd><p>
3687 <code class="computeroutput"><span class="identifier">future_error</span></code>
3688 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
3689 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>.
3690 </p></dd>
3691<dt><span class="term">Note:</span></dt>
3692<dd><p>
3693 <code class="computeroutput"><span class="identifier">get_exception_ptr</span><span class="special">()</span></code> does <span class="emphasis"><em>not</em></span>
3694 invalidate the <code class="computeroutput">future</code>. After calling <code class="computeroutput"><span class="identifier">get_exception_ptr</span><span class="special">()</span></code>, you may still call <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a>.
3695 </p></dd>
3696</dl>
3697</div>
3698<p>
3699 </p>
3700<h5>
3701<a name="future_wait_bridgehead"></a>
3702 <span><a name="future_wait"></a></span>
3703 <a class="link" href="pooled_fixedsize.html#future_wait">Member function <code class="computeroutput">wait</code>()</a>
3704</h5>
3705<p>
3706 </p>
3707<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">wait</span><span class="special">();</span>
3708</pre>
3709<div class="variablelist">
3710<p class="title"><b></b></p>
3711<dl>
3712<dt><span class="term">Effects:</span></dt>
3713<dd><p>
3714 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3715 called.
3716 </p></dd>
3717<dt><span class="term">Throws:</span></dt>
3718<dd><p>
3719 <code class="computeroutput"><span class="identifier">future_error</span></code>
3720 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
3721 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>.
3722 </p></dd>
3723</dl>
3724</div>
3725<p>
3726 </p>
3727<h5>
3728<a name="future_wait_for_bridgehead"></a>
3729 <span><a name="future_wait_for"></a></span>
3730 <a class="link" href="pooled_fixedsize.html#future_wait_for">Templated
3731 member function <code class="computeroutput">wait_for</code>()</a>
3732</h5>
3733<p>
3734 </p>
3735<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
3736<span class="identifier">future_status</span> <span class="identifier">wait_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3737</pre>
3738<div class="variablelist">
3739<p class="title"><b></b></p>
3740<dl>
3741<dt><span class="term">Effects:</span></dt>
3742<dd><p>
3743 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3744 called, or <code class="computeroutput"><span class="identifier">timeout_duration</span></code>
3745 has passed.
3746 </p></dd>
3747<dt><span class="term">Result:</span></dt>
3748<dd><p>
3749 A <code class="computeroutput"><span class="identifier">future_status</span></code>
3750 is returned indicating the reason for returning.
3751 </p></dd>
3752<dt><span class="term">Throws:</span></dt>
3753<dd><p>
3754 <code class="computeroutput"><span class="identifier">future_error</span></code>
3755 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
3756 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3757 or timeout-related exceptions.
3758 </p></dd>
3759</dl>
3760</div>
3761<p>
3762 </p>
3763<h5>
3764<a name="future_wait_until_bridgehead"></a>
3765 <span><a name="future_wait_until"></a></span>
3766 <a class="link" href="pooled_fixedsize.html#future_wait_until">Templated
3767 member function <code class="computeroutput">wait_until</code>()</a>
3768</h5>
3769<p>
3770 </p>
3771<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
3772<span class="identifier">future_status</span> <span class="identifier">wait_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3773</pre>
3774<div class="variablelist">
3775<p class="title"><b></b></p>
3776<dl>
3777<dt><span class="term">Effects:</span></dt>
3778<dd><p>
3779 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
3780 called, or <code class="computeroutput"><span class="identifier">timeout_time</span></code>
3781 has passed.
3782 </p></dd>
3783<dt><span class="term">Result:</span></dt>
3784<dd><p>
3785 A <code class="computeroutput"><span class="identifier">future_status</span></code>
3786 is returned indicating the reason for returning.
3787 </p></dd>
3788<dt><span class="term">Throws:</span></dt>
3789<dd><p>
3790 <code class="computeroutput"><span class="identifier">future_error</span></code>
3791 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
3792 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
3793 or timeout-related exceptions.
3794 </p></dd>
3795</dl>
3796</div>
3797<p>
3798 </p>
3799<h5>
3800<a name="class_shared_future_bridgehead"></a>
3801 <span><a name="class_shared_future"></a></span>
3802 <a class="link" href="pooled_fixedsize.html#class_shared_future">Template
3803 <code class="computeroutput">shared_future&lt;&gt;</code></a>
3804</h5>
3805<p>
3806 </p>
3807<p>
3808 A <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> contains a <a class="link" href="pooled_fixedsize.html#shared_state">shared
3809 state</a> which might be shared with other <a class="link" href="pooled_fixedsize.html#class_shared_future"> <code class="computeroutput">shared_future&lt;&gt;</code></a> instances.
3810 </p>
3811<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">R</span> <span class="special">&gt;</span>
3812<span class="keyword">class</span> <span class="identifier">shared_future</span> <span class="special">{</span>
3813<span class="keyword">public</span><span class="special">:</span>
3814 <span class="identifier">shared_future</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
3815
3816 <span class="special">~</span><span class="identifier">shared_future</span><span class="special">();</span>
3817
3818 <span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">shared_future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">);</span>
3819
3820 <span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3821
3822 <span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">shared_future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3823
3824 <span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">shared_future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3825
3826 <span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3827
3828 <span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">shared_future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3829
3830 <span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
3831
3832 <span class="identifier">R</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of generic shared_future template</span>
3833 <span class="identifier">R</span> <span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of shared_future&lt; R &amp; &gt; template specialization</span>
3834 <span class="keyword">void</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of shared_future&lt; void &gt; template specialization</span>
3835
3836 <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">get_exception_ptr</span><span class="special">();</span>
3837
3838 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">()</span> <span class="keyword">const</span><span class="special">;</span>
3839
3840 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
3841 <span class="identifier">future_status</span> <span class="identifier">wait_for</span><span class="special">(</span>
3842 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3843
3844 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
3845 <span class="identifier">future_status</span> <span class="identifier">wait_until</span><span class="special">(</span>
3846 <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
3847<span class="special">};</span>
3848</pre>
3849<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h7"></a>
3850 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.default_constructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.default_constructor0">Default
3851 constructor</a>
3852 </h8><pre class="programlisting"><span class="identifier">shared_future</span><span class="special">();</span>
3853</pre>
3854<div class="variablelist">
3855<p class="title"><b></b></p>
3856<dl>
3857<dt><span class="term">Effects:</span></dt>
3858<dd><p>
3859 Creates a shared_future with no <a class="link" href="pooled_fixedsize.html#shared_state">shared
3860 state</a>. After construction <code class="computeroutput"><span class="keyword">false</span>
3861 <span class="special">==</span> <span class="identifier">valid</span><span class="special">()</span></code>.
3862 </p></dd>
3863<dt><span class="term">Throws:</span></dt>
3864<dd><p>
3865 Nothing.
3866 </p></dd>
3867</dl>
3868</div>
3869<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h8"></a>
3870 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.move_constructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.move_constructor0">Move
3871 constructor</a>
3872 </h8><pre class="programlisting"><span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3873<span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">shared_future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3874</pre>
3875<div class="variablelist">
3876<p class="title"><b></b></p>
3877<dl>
3878<dt><span class="term">Effects:</span></dt>
3879<dd><p>
3880 Constructs a shared_future with the <a class="link" href="pooled_fixedsize.html#shared_state">shared
3881 state</a> of other. After construction <code class="computeroutput"><span class="keyword">false</span>
3882 <span class="special">==</span> <span class="identifier">other</span><span class="special">.</span><span class="identifier">valid</span><span class="special">()</span></code>.
3883 </p></dd>
3884<dt><span class="term">Throws:</span></dt>
3885<dd><p>
3886 Nothing.
3887 </p></dd>
3888</dl>
3889</div>
3890<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h9"></a>
3891 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.copy_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.copy_constructor">Copy
3892 constructor</a>
3893 </h8><pre class="programlisting"><span class="identifier">shared_future</span><span class="special">(</span> <span class="identifier">shared_future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3894</pre>
3895<div class="variablelist">
3896<p class="title"><b></b></p>
3897<dl>
3898<dt><span class="term">Effects:</span></dt>
3899<dd><p>
3900 Constructs a shared_future with the <a class="link" href="pooled_fixedsize.html#shared_state">shared
3901 state</a> of other. After construction <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">valid</span><span class="special">()</span></code> is unchanged.
3902 </p></dd>
3903<dt><span class="term">Throws:</span></dt>
3904<dd><p>
3905 Nothing.
3906 </p></dd>
3907</dl>
3908</div>
3909<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.h10"></a>
3910 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.destructor0"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.future.destructor0">Destructor</a>
3911 </h8><pre class="programlisting"><span class="special">~</span><span class="identifier">shared_future</span><span class="special">();</span>
3912</pre>
3913<div class="variablelist">
3914<p class="title"><b></b></p>
3915<dl>
3916<dt><span class="term">Effects:</span></dt>
3917<dd><p>
3918 Destroys the shared_future; ownership is abandoned if not shared.
3919 </p></dd>
3920<dt><span class="term">Note:</span></dt>
3921<dd><p>
3922 <code class="computeroutput">~shared_future()</code> does <span class="emphasis"><em>not</em></span> block the calling
3923 fiber.
3924 </p></dd>
3925</dl>
3926</div>
3927<p>
3928 </p>
3929<h5>
3930<a name="shared_future_operator_assign_bridgehead"></a>
3931 <span><a name="shared_future_operator_assign"></a></span>
3932 <a class="link" href="pooled_fixedsize.html#shared_future_operator_assign">Member
3933 function <code class="computeroutput">operator=</code>()</a>
3934</h5>
3935<p>
3936 </p>
3937<pre class="programlisting"><span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3938<span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">shared_future</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3939<span class="identifier">shared_future</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">shared_future</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
3940</pre>
3941<div class="variablelist">
3942<p class="title"><b></b></p>
3943<dl>
3944<dt><span class="term">Effects:</span></dt>
3945<dd><p>
3946 Moves or copies the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
3947 of other to <code class="computeroutput"><span class="keyword">this</span></code>.
3948 After the assignment, the state of <code class="computeroutput"><span class="identifier">other</span><span class="special">.</span><span class="identifier">valid</span><span class="special">()</span></code> depends on which overload
3949 was invoked: unchanged for the overload accepting <code class="computeroutput"><span class="identifier">shared_future</span> <span class="keyword">const</span><span class="special">&amp;</span></code>, otherwise <code class="computeroutput"><span class="keyword">false</span></code>.
3950 </p></dd>
3951<dt><span class="term">Throws:</span></dt>
3952<dd><p>
3953 Nothing.
3954 </p></dd>
3955</dl>
3956</div>
3957<p>
3958 </p>
3959<h5>
3960<a name="shared_future_valid_bridgehead"></a>
3961 <span><a name="shared_future_valid"></a></span>
3962 <a class="link" href="pooled_fixedsize.html#shared_future_valid">Member
3963 function <code class="computeroutput">valid</code>()</a>
3964</h5>
3965<p>
3966 </p>
3967<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
3968</pre>
3969<div class="variablelist">
3970<p class="title"><b></b></p>
3971<dl>
3972<dt><span class="term">Effects:</span></dt>
3973<dd><p>
3974 Returns <code class="computeroutput"><span class="keyword">true</span></code> if
3975 shared_future contains a <a class="link" href="pooled_fixedsize.html#shared_state">shared
3976 state</a>.
3977 </p></dd>
3978<dt><span class="term">Throws:</span></dt>
3979<dd><p>
3980 Nothing.
3981 </p></dd>
3982</dl>
3983</div>
3984<p>
3985 </p>
3986<h5>
3987<a name="shared_future_get_bridgehead"></a>
3988 <span><a name="shared_future_get"></a></span>
3989 <a class="link" href="pooled_fixedsize.html#shared_future_get">Member
3990 function <code class="computeroutput">get</code>()</a>
3991</h5>
3992<p>
3993 </p>
3994<pre class="programlisting"><span class="identifier">R</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of generic shared_future template</span>
3995<span class="identifier">R</span> <span class="special">&amp;</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of shared_future&lt; R &amp; &gt; template specialization</span>
3996<span class="keyword">void</span> <span class="identifier">get</span><span class="special">();</span> <span class="comment">// member only of shared_future&lt; void &gt; template specialization</span>
3997</pre>
3998<div class="variablelist">
3999<p class="title"><b></b></p>
4000<dl>
4001<dt><span class="term">Precondition:</span></dt>
4002<dd><p>
4003 <code class="computeroutput"><span class="keyword">true</span> <span class="special">==</span>
4004 <span class="identifier">valid</span><span class="special">()</span></code>
4005 </p></dd>
4006<dt><span class="term">Returns:</span></dt>
4007<dd><p>
4008 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4009 called. If <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> is called,
4010 returns the value. If <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4011 called, throws the indicated exception.
4012 </p></dd>
4013<dt><span class="term">Postcondition:</span></dt>
4014<dd><p>
4015 <code class="computeroutput"><span class="keyword">false</span> <span class="special">==</span>
4016 <span class="identifier">valid</span><span class="special">()</span></code>
4017 </p></dd>
4018<dt><span class="term">Throws:</span></dt>
4019<dd><p>
4020 <code class="computeroutput"><span class="identifier">future_error</span></code>
4021 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>,
4022 <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>,
4023 <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">broken_promise</span></code>.
4024 Any exception passed to <code class="computeroutput"><span class="identifier">promise</span><span class="special">::</span><span class="identifier">set_exception</span><span class="special">()</span></code>.
4025 </p></dd>
4026</dl>
4027</div>
4028<p>
4029 </p>
4030<h5>
4031<a name="shared_future_get_exception_ptr_bridgehead"></a>
4032 <span><a name="shared_future_get_exception_ptr"></a></span>
4033 <a class="link" href="pooled_fixedsize.html#shared_future_get_exception_ptr">Member
4034 function <code class="computeroutput">get_exception_ptr</code>()</a>
4035</h5>
4036<p>
4037 </p>
4038<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">get_exception_ptr</span><span class="special">();</span>
4039</pre>
4040<div class="variablelist">
4041<p class="title"><b></b></p>
4042<dl>
4043<dt><span class="term">Precondition:</span></dt>
4044<dd><p>
4045 <code class="computeroutput"><span class="keyword">true</span> <span class="special">==</span>
4046 <span class="identifier">valid</span><span class="special">()</span></code>
4047 </p></dd>
4048<dt><span class="term">Returns:</span></dt>
4049<dd><p>
4050 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4051 called. If <code class="computeroutput"><span class="identifier">set_value</span><span class="special">()</span></code> is called, returns a default-constructed
4052 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>. If <code class="computeroutput"><span class="identifier">set_exception</span><span class="special">()</span></code>
4053 is called, returns the passed <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>.
4054 </p></dd>
4055<dt><span class="term">Throws:</span></dt>
4056<dd><p>
4057 <code class="computeroutput"><span class="identifier">future_error</span></code>
4058 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
4059 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>.
4060 </p></dd>
4061<dt><span class="term">Note:</span></dt>
4062<dd><p>
4063 <code class="computeroutput"><span class="identifier">get_exception_ptr</span><span class="special">()</span></code> does <span class="emphasis"><em>not</em></span>
4064 invalidate the <code class="computeroutput">shared_future</code>. After calling <code class="computeroutput"><span class="identifier">get_exception_ptr</span><span class="special">()</span></code>, you may still call <a class="link" href="pooled_fixedsize.html#shared_future_get"> <code class="computeroutput">shared_future::get()</code></a>.
4065 </p></dd>
4066</dl>
4067</div>
4068<p>
4069 </p>
4070<h5>
4071<a name="shared_future_wait_bridgehead"></a>
4072 <span><a name="shared_future_wait"></a></span>
4073 <a class="link" href="pooled_fixedsize.html#shared_future_wait">Member
4074 function <code class="computeroutput">wait</code>()</a>
4075</h5>
4076<p>
4077 </p>
4078<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">wait</span><span class="special">();</span>
4079</pre>
4080<div class="variablelist">
4081<p class="title"><b></b></p>
4082<dl>
4083<dt><span class="term">Effects:</span></dt>
4084<dd><p>
4085 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4086 called.
4087 </p></dd>
4088<dt><span class="term">Throws:</span></dt>
4089<dd><p>
4090 <code class="computeroutput"><span class="identifier">future_error</span></code>
4091 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
4092 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>.
4093 </p></dd>
4094</dl>
4095</div>
4096<p>
4097 </p>
4098<h5>
4099<a name="shared_future_wait_for_bridgehead"></a>
4100 <span><a name="shared_future_wait_for"></a></span>
4101 <a class="link" href="pooled_fixedsize.html#shared_future_wait_for">Templated
4102 member function <code class="computeroutput">wait_for</code>()</a>
4103</h5>
4104<p>
4105 </p>
4106<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Period</span> <span class="special">&gt;</span>
4107<span class="identifier">future_status</span> <span class="identifier">wait_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">duration</span><span class="special">&lt;</span> <span class="identifier">Rep</span><span class="special">,</span> <span class="identifier">Period</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_duration</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
4108</pre>
4109<div class="variablelist">
4110<p class="title"><b></b></p>
4111<dl>
4112<dt><span class="term">Effects:</span></dt>
4113<dd><p>
4114 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4115 called, or <code class="computeroutput"><span class="identifier">timeout_duration</span></code>
4116 has passed.
4117 </p></dd>
4118<dt><span class="term">Result:</span></dt>
4119<dd><p>
4120 A <code class="computeroutput"><span class="identifier">future_status</span></code>
4121 is returned indicating the reason for returning.
4122 </p></dd>
4123<dt><span class="term">Throws:</span></dt>
4124<dd><p>
4125 <code class="computeroutput"><span class="identifier">future_error</span></code>
4126 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
4127 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
4128 or timeout-related exceptions.
4129 </p></dd>
4130</dl>
4131</div>
4132<p>
4133 </p>
4134<h5>
4135<a name="shared_future_wait_until_bridgehead"></a>
4136 <span><a name="shared_future_wait_until"></a></span>
4137 <a class="link" href="pooled_fixedsize.html#shared_future_wait_until">Templated
4138 member function <code class="computeroutput">wait_until</code>()</a>
4139</h5>
4140<p>
4141 </p>
4142<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Duration</span> <span class="special">&gt;</span>
4143<span class="identifier">future_status</span> <span class="identifier">wait_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">&lt;</span> <span class="identifier">Clock</span><span class="special">,</span> <span class="identifier">Duration</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">timeout_time</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
4144</pre>
4145<div class="variablelist">
4146<p class="title"><b></b></p>
4147<dl>
4148<dt><span class="term">Effects:</span></dt>
4149<dd><p>
4150 Waits until <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> or <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a> is
4151 called, or <code class="computeroutput"><span class="identifier">timeout_time</span></code>
4152 has passed.
4153 </p></dd>
4154<dt><span class="term">Result:</span></dt>
4155<dd><p>
4156 A <code class="computeroutput"><span class="identifier">future_status</span></code>
4157 is returned indicating the reason for returning.
4158 </p></dd>
4159<dt><span class="term">Throws:</span></dt>
4160<dd><p>
4161 <code class="computeroutput"><span class="identifier">future_error</span></code>
4162 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>
4163 or <code class="computeroutput"><span class="identifier">fiber_interrupted</span></code>
4164 or timeout-related exceptions.
4165 </p></dd>
4166</dl>
4167</div>
4168<p>
4169 </p>
4170<h5>
4171<a name="fibers_async_bridgehead"></a>
4172 <span><a name="fibers_async"></a></span>
4173 <a class="link" href="pooled_fixedsize.html#fibers_async">Non-member function
4174 <code class="computeroutput">fibers::async()</code></a>
4175</h5>
4176<p>
4177 </p>
4178<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">future</span><span class="special">/</span><span class="identifier">async</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4179
4180<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span> <span class="keyword">class</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
4181<span class="identifier">future</span><span class="special">&lt;</span>
4182 <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of_t</span><span class="special">&lt;</span>
4183 <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Function</span> <span class="special">&gt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Args</span> <span class="special">&gt;</span> <span class="special">...</span> <span class="special">)</span>
4184 <span class="special">&gt;</span>
4185<span class="special">&gt;</span>
4186<span class="identifier">async</span><span class="special">(</span> <span class="identifier">Function</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
4187
4188<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <a class="link" href="../../stack.html#stack_allocator_concept"><code class="computeroutput"><span class="identifier">StackAllocator</span></code></a><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span> <span class="keyword">class</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
4189<span class="identifier">future</span><span class="special">&lt;</span>
4190 <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of_t</span><span class="special">&lt;</span>
4191 <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Function</span> <span class="special">&gt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Args</span> <span class="special">&gt;</span> <span class="special">...</span> <span class="special">)</span>
4192 <span class="special">&gt;</span>
4193<span class="special">&gt;</span>
4194<span class="identifier">async</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a><span class="special">,</span> <a class="link" href="../../stack.html#stack_allocator_concept"><code class="computeroutput"><span class="identifier">StackAllocator</span></code></a> <span class="identifier">salloc</span><span class="special">,</span> <span class="identifier">Function</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">,</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
4195</pre>
4196<div class="variablelist">
4197<p class="title"><b></b></p>
4198<dl>
4199<dt><span class="term">Effects:</span></dt>
4200<dd><p>
4201 Executes <code class="computeroutput"><span class="identifier">fn</span></code>
4202 in a <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> and returns an associated <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a>.
4203 </p></dd>
4204<dt><span class="term">Result:</span></dt>
4205<dd>
4206<p>
4207</p>
4208<pre class="programlisting"><span class="identifier">future</span><span class="special">&lt;</span>
4209 <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of_t</span><span class="special">&lt;</span>
4210 <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Function</span> <span class="special">&gt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay_t</span><span class="special">&lt;</span> <span class="identifier">Args</span> <span class="special">&gt;</span> <span class="special">...</span> <span class="special">)</span>
4211 <span class="special">&gt;</span>
4212<span class="special">&gt;</span></pre>
4213<p>
4214 representing the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4215 associated with the asynchronous execution of <code class="computeroutput"><span class="identifier">fn</span></code>.
4216 </p>
4217</dd>
4218<dt><span class="term">Throws:</span></dt>
4219<dd><p>
4220 <code class="computeroutput"><span class="identifier">fiber_error</span></code>
4221 or <code class="computeroutput"><span class="identifier">future_error</span></code>
4222 if an error occurs.
4223 </p></dd>
4224<dt><span class="term">Notes:</span></dt>
4225<dd><p>
4226 The overload accepting <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a> uses
4227 the passed <a class="link" href="../../stack.html#stack_allocator_concept"><code class="computeroutput"><span class="identifier">StackAllocator</span></code></a> when
4228 constructing the launched <code class="computeroutput"><span class="identifier">fiber</span></code>.
4229 </p></dd>
4230</dl>
4231</div>
4232<div class="note"><table border="0" summary="Note">
4233<tr>
4234<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
4235<th align="left">Note</th>
4236</tr>
4237<tr><td align="left" valign="top"><p>
4238 Deferred futures are not supported.
4239 </p></td></tr>
4240</table></div>
4241</div>
4242<div class="section">
4243<div class="titlepage"><div><div><h6 class="title">
4244<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise"></a><a name="class_promise"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise" title="Template promise&lt;&gt;">Template
4245 <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code></a>
4246</h6></div></div></div>
4247<p>
4248 A <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> provides a mechanism to store a value
4249 (or exception) that can later be retrieved from the corresponding
4250 <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> object. <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code> and <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> communicate via their underlying
4251 <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>.
4252 </p>
4253<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">R</span> <span class="special">&gt;</span>
4254<span class="keyword">class</span> <span class="identifier">promise</span> <span class="special">{</span>
4255<span class="keyword">public</span><span class="special">:</span>
4256 <span class="identifier">promise</span><span class="special">();</span>
4257
4258 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">&gt;</span>
4259 <span class="identifier">promise</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a><span class="special">,</span> <span class="identifier">Allocator</span><span class="special">);</span>
4260
4261 <span class="identifier">promise</span><span class="special">(</span> <span class="identifier">promise</span> <span class="special">&amp;&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4262
4263 <span class="identifier">promise</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">promise</span> <span class="special">&amp;&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4264
4265 <span class="identifier">promise</span><span class="special">(</span> <span class="identifier">promise</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4266
4267 <span class="identifier">promise</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">promise</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4268
4269 <span class="special">~</span><span class="identifier">promise</span><span class="special">();</span>
4270
4271 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">promise</span> <span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4272
4273 <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>
4274
4275 <span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="keyword">const</span><span class="special">&amp;);</span> <span class="comment">// member only of generic promise template</span>
4276 <span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="special">&amp;&amp;);</span> <span class="comment">// member only of generic promise template</span>
4277 <span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="special">&amp;);</span> <span class="comment">// member only of promise&lt; R &amp; &gt; template</span>
4278 <span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">();</span> <span class="comment">// member only of promise&lt; void &gt; template</span>
4279
4280 <span class="keyword">void</span> <span class="identifier">set_exception</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">p</span><span class="special">);</span>
4281<span class="special">};</span>
4282
4283<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">R</span> <span class="special">&gt;</span>
4284<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;,</span> <span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4285</pre>
4286<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.h0"></a>
4287 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.default_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.default_constructor">Default
4288 constructor</a>
4289 </h8><pre class="programlisting"><span class="identifier">promise</span><span class="special">();</span>
4290</pre>
4291<div class="variablelist">
4292<p class="title"><b></b></p>
4293<dl>
4294<dt><span class="term">Effects:</span></dt>
4295<dd><p>
4296 Creates a promise with an empty <a class="link" href="pooled_fixedsize.html#shared_state">shared
4297 state</a>.
4298 </p></dd>
4299<dt><span class="term">Throws:</span></dt>
4300<dd><p>
4301 Exceptions caused by memory allocation.
4302 </p></dd>
4303</dl>
4304</div>
4305<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.h1"></a>
4306 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.constructor">Constructor</a>
4307 </h8><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">&gt;</span>
4308<span class="identifier">promise</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a><span class="special">,</span> <span class="identifier">Allocator</span> <span class="identifier">alloc</span><span class="special">);</span>
4309</pre>
4310<div class="variablelist">
4311<p class="title"><b></b></p>
4312<dl>
4313<dt><span class="term">Effects:</span></dt>
4314<dd><p>
4315 Creates a promise with an empty <a class="link" href="pooled_fixedsize.html#shared_state">shared
4316 state</a> by using <code class="computeroutput"><span class="identifier">alloc</span></code>.
4317 </p></dd>
4318<dt><span class="term">Throws:</span></dt>
4319<dd><p>
4320 Exceptions caused by memory allocation.
4321 </p></dd>
4322<dt><span class="term">See also:</span></dt>
4323<dd><p>
4324 <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a>
4325 </p></dd>
4326</dl>
4327</div>
4328<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.h2"></a>
4329 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.move_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.move_constructor">Move
4330 constructor</a>
4331 </h8><pre class="programlisting"><span class="identifier">promise</span><span class="special">(</span> <span class="identifier">promise</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4332</pre>
4333<div class="variablelist">
4334<p class="title"><b></b></p>
4335<dl>
4336<dt><span class="term">Effects:</span></dt>
4337<dd><p>
4338 Creates a promise by moving the <a class="link" href="pooled_fixedsize.html#shared_state">shared
4339 state</a> from <code class="computeroutput"><span class="identifier">other</span></code>.
4340 </p></dd>
4341<dt><span class="term">Postcondition:</span></dt>
4342<dd><p>
4343 <code class="computeroutput"><span class="identifier">other</span></code> contains
4344 no valid shared state.
4345 </p></dd>
4346<dt><span class="term">Throws:</span></dt>
4347<dd><p>
4348 Nothing.
4349 </p></dd>
4350</dl>
4351</div>
4352<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.h3"></a>
4353 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.destructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.promise.destructor">Destructor</a>
4354 </h8><pre class="programlisting"><span class="special">~</span><span class="identifier">promise</span><span class="special">();</span>
4355</pre>
4356<div class="variablelist">
4357<p class="title"><b></b></p>
4358<dl>
4359<dt><span class="term">Effects:</span></dt>
4360<dd><p>
4361 Destroys <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
4362 and abandons the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4363 if shared state is ready; otherwise stores <code class="computeroutput"><span class="identifier">future_error</span></code>
4364 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">broken_promise</span></code>
4365 as if by <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a>: the
4366 shared state is set ready.
4367 </p></dd>
4368</dl>
4369</div>
4370<p>
4371 </p>
4372<h5>
4373<a name="promise_operator_assign_bridgehead"></a>
4374 <span><a name="promise_operator_assign"></a></span>
4375 <a class="link" href="pooled_fixedsize.html#promise_operator_assign">Member
4376 function <code class="computeroutput">operator=</code>()</a>
4377</h5>
4378<p>
4379 </p>
4380<pre class="programlisting"><span class="identifier">promise</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">promise</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4381</pre>
4382<div class="variablelist">
4383<p class="title"><b></b></p>
4384<dl>
4385<dt><span class="term">Effects:</span></dt>
4386<dd><p>
4387 Transfers the ownership of <a class="link" href="pooled_fixedsize.html#shared_state">shared
4388 state</a> to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
4389 </p></dd>
4390<dt><span class="term">Postcondition:</span></dt>
4391<dd><p>
4392 <code class="computeroutput"><span class="identifier">other</span></code> contains
4393 no valid shared state.
4394 </p></dd>
4395<dt><span class="term">Throws:</span></dt>
4396<dd><p>
4397 Nothing.
4398 </p></dd>
4399</dl>
4400</div>
4401<p>
4402 </p>
4403<h5>
4404<a name="promise_swap_bridgehead"></a>
4405 <span><a name="promise_swap"></a></span>
4406 <a class="link" href="pooled_fixedsize.html#promise_swap">Member function <code class="computeroutput">swap</code>()</a>
4407</h5>
4408<p>
4409 </p>
4410<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">promise</span> <span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4411</pre>
4412<div class="variablelist">
4413<p class="title"><b></b></p>
4414<dl>
4415<dt><span class="term">Effects:</span></dt>
4416<dd><p>
4417 Swaps the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4418 between other and <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
4419 </p></dd>
4420<dt><span class="term">Throws:</span></dt>
4421<dd><p>
4422 Nothing.
4423 </p></dd>
4424</dl>
4425</div>
4426<p>
4427 </p>
4428<h5>
4429<a name="promise_get_future_bridgehead"></a>
4430 <span><a name="promise_get_future"></a></span>
4431 <a class="link" href="pooled_fixedsize.html#promise_get_future">Member
4432 function <code class="computeroutput">get_future</code>()</a>
4433</h5>
4434<p>
4435 </p>
4436<pre class="programlisting"><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>
4437</pre>
4438<div class="variablelist">
4439<p class="title"><b></b></p>
4440<dl>
4441<dt><span class="term">Returns:</span></dt>
4442<dd><p>
4443 A <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> with the same <a class="link" href="pooled_fixedsize.html#shared_state">shared
4444 state</a>.
4445 </p></dd>
4446<dt><span class="term">Throws:</span></dt>
4447<dd><p>
4448 <code class="computeroutput"><span class="identifier">future_error</span></code>
4449 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">future_already_retrieved</span></code>
4450 or <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4451 </p></dd>
4452</dl>
4453</div>
4454<p>
4455 </p>
4456<h5>
4457<a name="promise_set_value_bridgehead"></a>
4458 <span><a name="promise_set_value"></a></span>
4459 <a class="link" href="pooled_fixedsize.html#promise_set_value">Member
4460 function <code class="computeroutput">set_value</code>()</a>
4461</h5>
4462<p>
4463 </p>
4464<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">value</span><span class="special">);</span> <span class="comment">// member only of generic promise template</span>
4465<span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="special">&amp;&amp;</span> <span class="identifier">value</span><span class="special">);</span> <span class="comment">// member only of generic promise template</span>
4466<span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">R</span> <span class="special">&amp;</span> <span class="identifier">value</span><span class="special">);</span> <span class="comment">// member only of promise&lt; R &amp; &gt; template</span>
4467<span class="keyword">void</span> <span class="identifier">set_value</span><span class="special">();</span> <span class="comment">// member only of promise&lt; void &gt; template</span>
4468</pre>
4469<div class="variablelist">
4470<p class="title"><b></b></p>
4471<dl>
4472<dt><span class="term">Effects:</span></dt>
4473<dd><p>
4474 Store the result in the <a class="link" href="pooled_fixedsize.html#shared_state">shared
4475 state</a> and marks the state as ready.
4476 </p></dd>
4477<dt><span class="term">Throws:</span></dt>
4478<dd><p>
4479 <code class="computeroutput"><span class="identifier">future_error</span></code>
4480 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">future_already_satisfied</span></code>
4481 or <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4482 </p></dd>
4483</dl>
4484</div>
4485<p>
4486 </p>
4487<h5>
4488<a name="promise_set_exception_bridgehead"></a>
4489 <span><a name="promise_set_exception"></a></span>
4490 <a class="link" href="pooled_fixedsize.html#promise_set_exception">Member
4491 function <code class="computeroutput">set_exception</code>()</a>
4492</h5>
4493<p>
4494 </p>
4495<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">set_exception</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span><span class="special">);</span>
4496</pre>
4497<div class="variablelist">
4498<p class="title"><b></b></p>
4499<dl>
4500<dt><span class="term">Effects:</span></dt>
4501<dd><p>
4502 Store an exception pointer in the <a class="link" href="pooled_fixedsize.html#shared_state">shared
4503 state</a> and marks the state as ready.
4504 </p></dd>
4505<dt><span class="term">Throws:</span></dt>
4506<dd><p>
4507 <code class="computeroutput"><span class="identifier">future_error</span></code>
4508 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">future_already_satisfied</span></code>
4509 or <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4510 </p></dd>
4511</dl>
4512</div>
4513<p>
4514 </p>
4515<h5>
4516<a name="swap_for_promise_bridgehead"></a>
4517 <span><a name="swap_for_promise"></a></span>
4518 <a class="link" href="pooled_fixedsize.html#swap_for_promise">Non-member
4519 function <code class="computeroutput">swap()</code></a>
4520</h5>
4521<p>
4522 </p>
4523<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">R</span> <span class="special">&gt;</span>
4524<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">r</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4525</pre>
4526<div class="variablelist">
4527<p class="title"><b></b></p>
4528<dl>
4529<dt><span class="term">Effects:</span></dt>
4530<dd><p>
4531 Same as <code class="computeroutput"><span class="identifier">l</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span>
4532 <span class="identifier">r</span><span class="special">)</span></code>.
4533 </p></dd>
4534</dl>
4535</div>
4536</div>
4537<div class="section">
4538<div class="titlepage"><div><div><h6 class="title">
4539<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task"></a><a name="class_packaged_task"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task" title="Template packaged_task&lt;&gt;">Template
4540 <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code></a>
4541</h6></div></div></div>
4542<p>
4543 A <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a> wraps a callable target
4544 that returns a value so that the return value can be computed asynchronously.
4545 </p>
4546<p>
4547 Conventional usage of <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code> is like this:
4548 </p>
4549<div class="orderedlist"><ol class="orderedlist" type="1">
4550<li class="listitem">
4551 Instantiate <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code> with template arguments
4552 matching the signature of the callable. Pass the callable to
4553 the <a class="link" href="pooled_fixedsize.html#packaged_task_packaged_task">constructor</a>.
4554 </li>
4555<li class="listitem">
4556 Call <a class="link" href="pooled_fixedsize.html#packaged_task_get_future"> <code class="computeroutput">packaged_task::get_future()</code></a> and capture
4557 the returned <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> instance.
4558 </li>
4559<li class="listitem">
4560 Launch a <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> to run the new <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code>, passing any arguments
4561 required by the original callable.
4562 </li>
4563<li class="listitem">
4564 Call <a class="link" href="../../fiber_mgmt/fiber.html#fiber_detach"> <code class="computeroutput">fiber::detach()</code></a> on the newly-launched <code class="computeroutput"><span class="identifier">fiber</span></code>.
4565 </li>
4566<li class="listitem">
4567 At some later point, retrieve the result from the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>.
4568 </li>
4569</ol></div>
4570<p>
4571 This is, in fact, pretty much what <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a>
4572encapsulates.
4573 </p>
4574<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">class</span> <span class="identifier">R</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Args</span> <span class="special">&gt;</span>
4575<span class="keyword">class</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">R</span><span class="special">(</span> <span class="identifier">Args</span> <span class="special">...</span> <span class="special">)</span> <span class="special">&gt;</span> <span class="special">{</span>
4576<span class="keyword">public</span><span class="special">:</span>
4577 <span class="identifier">packaged_task</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
4578
4579 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
4580 <span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;);</span>
4581
4582 <span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">&gt;</span>
4583 <span class="identifier">packaged_task</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a><span class="special">,</span> <span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&amp;,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;);</span>
4584
4585 <span class="identifier">packaged_task</span><span class="special">(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4586
4587 <span class="identifier">packaged_task</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4588
4589 <span class="identifier">packaged_task</span><span class="special">(</span> <span class="identifier">packaged_task</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4590
4591 <span class="identifier">packaged_task</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">packaged_task</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4592
4593 <span class="special">~</span><span class="identifier">packaged_task</span><span class="special">();</span>
4594
4595 <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4596
4597 <span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
4598
4599 <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>
4600
4601 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">Args</span> <span class="special">...);</span>
4602
4603 <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
4604<span class="special">};</span>
4605
4606<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Signature</span> <span class="special">&gt;</span>
4607<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">Signature</span> <span class="special">&gt;</span> <span class="special">&amp;,</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">Signature</span> <span class="special">&gt;</span> <span class="special">&amp;)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4608</pre>
4609<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.h0"></a>
4610 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.default_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.default_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_">Default
4611 constructor <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">()</span></code></a>
4612 </h8><pre class="programlisting"><span class="identifier">packaged_task</span><span class="special">()</span> <span class="keyword">noexcept</span><span class="special">;</span>
4613</pre>
4614<div class="variablelist">
4615<p class="title"><b></b></p>
4616<dl>
4617<dt><span class="term">Effects:</span></dt>
4618<dd><p>
4619 Constructs an object of class <code class="computeroutput"><span class="identifier">packaged_task</span></code>
4620 with no <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>.
4621 </p></dd>
4622<dt><span class="term">Throws:</span></dt>
4623<dd><p>
4624 Nothing.
4625 </p></dd>
4626</dl>
4627</div>
4628<a name="packaged_task_packaged_task"></a><h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.h1"></a>
4629 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.templated_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.templated_constructor__code__phrase_role__identifier__packaged_task__phrase__phrase_role__special______phrase___code_">Templated
4630 constructor <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">()</span></code></a>
4631 </h8><pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
4632<span class="keyword">explicit</span> <span class="identifier">packaged_task</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
4633
4634<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <a href="http://en.cppreference.com/w/cpp/concept/Allocator" target="_top"><code class="computeroutput"><span class="identifier">Allocator</span></code></a> <span class="special">&gt;</span>
4635<span class="identifier">packaged_task</span><span class="special">(</span> <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a><span class="special">,</span> <span class="identifier">Allocator</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">alloc</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">fn</span><span class="special">);</span>
4636</pre>
4637<div class="variablelist">
4638<p class="title"><b></b></p>
4639<dl>
4640<dt><span class="term">Effects:</span></dt>
4641<dd><p>
4642 Constructs an object of class <code class="computeroutput"><span class="identifier">packaged_task</span></code>
4643 with a <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a> and
4644 copies or moves the callable target <code class="computeroutput"><span class="identifier">fn</span></code>
4645 to internal storage.
4646 </p></dd>
4647<dt><span class="term">Throws:</span></dt>
4648<dd><p>
4649 Exceptions caused by memory allocation.
4650 </p></dd>
4651<dt><span class="term">Note:</span></dt>
4652<dd><p>
4653 The signature of <code class="computeroutput"><span class="identifier">Fn</span></code>
4654 should have a return type convertible to <code class="computeroutput"><span class="identifier">R</span></code>.
4655 </p></dd>
4656<dt><span class="term">See also:</span></dt>
4657<dd><p>
4658 <a href="http://en.cppreference.com/w/cpp/memory/allocator_arg_t" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">allocator_arg_t</span></code></a>
4659 </p></dd>
4660</dl>
4661</div>
4662<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.h2"></a>
4663 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.move_constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.move_constructor">Move
4664 constructor</a>
4665 </h8><pre class="programlisting"><span class="identifier">packaged_task</span><span class="special">(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4666</pre>
4667<div class="variablelist">
4668<p class="title"><b></b></p>
4669<dl>
4670<dt><span class="term">Effects:</span></dt>
4671<dd><p>
4672 Creates a packaged_task by moving the <a class="link" href="pooled_fixedsize.html#shared_state">shared
4673 state</a> from <code class="computeroutput"><span class="identifier">other</span></code>.
4674 </p></dd>
4675<dt><span class="term">Postcondition:</span></dt>
4676<dd><p>
4677 <code class="computeroutput"><span class="identifier">other</span></code> contains
4678 no valid shared state.
4679 </p></dd>
4680<dt><span class="term">Throws:</span></dt>
4681<dd><p>
4682 Nothing.
4683 </p></dd>
4684</dl>
4685</div>
4686<h8><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.h3"></a>
4687 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.destructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.futures.packaged_task.destructor">Destructor</a>
4688 </h8><pre class="programlisting"><span class="special">~</span><span class="identifier">packaged_task</span><span class="special">();</span>
4689</pre>
4690<div class="variablelist">
4691<p class="title"><b></b></p>
4692<dl>
4693<dt><span class="term">Effects:</span></dt>
4694<dd><p>
4695 Destroys <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
4696 and abandons the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4697 if shared state is ready; otherwise stores <code class="computeroutput"><span class="identifier">future_error</span></code>
4698 with error condition <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">broken_promise</span></code>
4699 as if by <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a>: the
4700 shared state is set ready.
4701 </p></dd>
4702</dl>
4703</div>
4704<p>
4705 </p>
4706<h5>
4707<a name="packaged_task_operator_assign_bridgehead"></a>
4708 <span><a name="packaged_task_operator_assign"></a></span>
4709 <a class="link" href="pooled_fixedsize.html#packaged_task_operator_assign">Member
4710 function <code class="computeroutput">operator=</code>()</a>
4711</h5>
4712<p>
4713 </p>
4714<pre class="programlisting"><span class="identifier">packaged_task</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4715</pre>
4716<div class="variablelist">
4717<p class="title"><b></b></p>
4718<dl>
4719<dt><span class="term">Effects:</span></dt>
4720<dd><p>
4721 Transfers the ownership of <a class="link" href="pooled_fixedsize.html#shared_state">shared
4722 state</a> to <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
4723 </p></dd>
4724<dt><span class="term">Postcondition:</span></dt>
4725<dd><p>
4726 <code class="computeroutput"><span class="identifier">other</span></code> contains
4727 no valid shared state.
4728 </p></dd>
4729<dt><span class="term">Throws:</span></dt>
4730<dd><p>
4731 Nothing.
4732 </p></dd>
4733</dl>
4734</div>
4735<p>
4736 </p>
4737<h5>
4738<a name="packaged_task_swap_bridgehead"></a>
4739 <span><a name="packaged_task_swap"></a></span>
4740 <a class="link" href="pooled_fixedsize.html#packaged_task_swap">Member
4741 function <code class="computeroutput">swap</code>()</a>
4742</h5>
4743<p>
4744 </p>
4745<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">packaged_task</span> <span class="special">&amp;</span> <span class="identifier">other</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4746</pre>
4747<div class="variablelist">
4748<p class="title"><b></b></p>
4749<dl>
4750<dt><span class="term">Effects:</span></dt>
4751<dd><p>
4752 Swaps the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4753 between other and <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
4754 </p></dd>
4755<dt><span class="term">Throws:</span></dt>
4756<dd><p>
4757 Nothing.
4758 </p></dd>
4759</dl>
4760</div>
4761<p>
4762 </p>
4763<h5>
4764<a name="packaged_task_valid_bridgehead"></a>
4765 <span><a name="packaged_task_valid"></a></span>
4766 <a class="link" href="pooled_fixedsize.html#packaged_task_valid">Member
4767 function <code class="computeroutput">valid</code>()</a>
4768</h5>
4769<p>
4770 </p>
4771<pre class="programlisting"><span class="keyword">bool</span> <span class="identifier">valid</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
4772</pre>
4773<div class="variablelist">
4774<p class="title"><b></b></p>
4775<dl>
4776<dt><span class="term">Effects:</span></dt>
4777<dd><p>
4778 Returns <code class="computeroutput"><span class="keyword">true</span></code> if
4779 <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
4780 contains a <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>.
4781 </p></dd>
4782<dt><span class="term">Throws:</span></dt>
4783<dd><p>
4784 Nothing.
4785 </p></dd>
4786</dl>
4787</div>
4788<p>
4789 </p>
4790<h5>
4791<a name="packaged_task_get_future_bridgehead"></a>
4792 <span><a name="packaged_task_get_future"></a></span>
4793 <a class="link" href="pooled_fixedsize.html#packaged_task_get_future">Member
4794 function <code class="computeroutput">get_future</code>()</a>
4795</h5>
4796<p>
4797 </p>
4798<pre class="programlisting"><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">R</span> <span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">();</span>
4799</pre>
4800<div class="variablelist">
4801<p class="title"><b></b></p>
4802<dl>
4803<dt><span class="term">Returns:</span></dt>
4804<dd><p>
4805 A <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> with the same <a class="link" href="pooled_fixedsize.html#shared_state">shared
4806 state</a>.
4807 </p></dd>
4808<dt><span class="term">Throws:</span></dt>
4809<dd><p>
4810 <code class="computeroutput"><span class="identifier">future_error</span></code>
4811 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">future_already_retrieved</span></code>
4812 or <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4813 </p></dd>
4814</dl>
4815</div>
4816<p>
4817 </p>
4818<h5>
4819<a name="packaged_task_operator_apply_bridgehead"></a>
4820 <span><a name="packaged_task_operator_apply"></a></span>
4821 <a class="link" href="pooled_fixedsize.html#packaged_task_operator_apply">Member
4822 function <code class="computeroutput">operator()</code>()</a>
4823</h5>
4824<p>
4825 </p>
4826<pre class="programlisting"><span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">Args</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">args</span><span class="special">);</span>
4827</pre>
4828<div class="variablelist">
4829<p class="title"><b></b></p>
4830<dl>
4831<dt><span class="term">Effects:</span></dt>
4832<dd><p>
4833 Invokes the stored callable target. Any exception thrown by
4834 the callable target <code class="computeroutput"><span class="identifier">fn</span></code>
4835 is stored in the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4836 as if by <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a>. Otherwise,
4837 the value returned by <code class="computeroutput"><span class="identifier">fn</span></code>
4838 is stored in the shared state as if by <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a>.
4839 </p></dd>
4840<dt><span class="term">Throws:</span></dt>
4841<dd><p>
4842 <code class="computeroutput"><span class="identifier">future_error</span></code>
4843 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4844 </p></dd>
4845</dl>
4846</div>
4847<p>
4848 </p>
4849<h5>
4850<a name="packaged_task_reset_bridgehead"></a>
4851 <span><a name="packaged_task_reset"></a></span>
4852 <a class="link" href="pooled_fixedsize.html#packaged_task_reset">Member
4853 function <code class="computeroutput">reset</code>()</a>
4854</h5>
4855<p>
4856 </p>
4857<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reset</span><span class="special">();</span>
4858</pre>
4859<div class="variablelist">
4860<p class="title"><b></b></p>
4861<dl>
4862<dt><span class="term">Effects:</span></dt>
4863<dd><p>
4864 Resets the <a class="link" href="pooled_fixedsize.html#shared_state">shared state</a>
4865 and abandons the result of previous executions. A new shared
4866 state is constructed.
4867 </p></dd>
4868<dt><span class="term">Throws:</span></dt>
4869<dd><p>
4870 <code class="computeroutput"><span class="identifier">future_error</span></code>
4871 with <code class="computeroutput"><span class="identifier">future_errc</span><span class="special">::</span><span class="identifier">no_state</span></code>.
4872 </p></dd>
4873</dl>
4874</div>
4875<p>
4876 </p>
4877<h5>
4878<a name="swap_for_packaged_task_bridgehead"></a>
4879 <span><a name="swap_for_packaged_task"></a></span>
4880 <a class="link" href="pooled_fixedsize.html#swap_for_packaged_task">Non-member
4881 function <code class="computeroutput">swap()</code></a>
4882</h5>
4883<p>
4884 </p>
4885<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Signature</span> <span class="special">&gt;</span>
4886<span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">Signature</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">l</span><span class="special">,</span> <span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">Signature</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">r</span><span class="special">)</span> <span class="keyword">noexcept</span><span class="special">;</span>
4887</pre>
4888<div class="variablelist">
4889<p class="title"><b></b></p>
4890<dl>
4891<dt><span class="term">Effects:</span></dt>
4892<dd><p>
4893 Same as <code class="computeroutput"><span class="identifier">l</span><span class="special">.</span><span class="identifier">swap</span><span class="special">(</span>
4894 <span class="identifier">r</span><span class="special">)</span></code>.
4895 </p></dd>
4896</dl>
4897</div>
4898</div>
4899</div>
4900</div>
4901<div class="section">
4902<div class="titlepage"><div><div><h5 class="title">
4903<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls" title="Fiber local storage">Fiber
4904 local storage</a>
4905</h5></div></div></div>
4906<h6>
4907<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.h0"></a>
4908 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.synopsis"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls.synopsis">Synopsis</a>
4909 </h6>
4910<p>
4911 Fiber local storage allows a separate instance of a given data item for
4912 each fiber.
4913 </p>
4914<h6>
4915<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.h1"></a>
4916 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.cleanup_at_fiber_exit"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls.cleanup_at_fiber_exit">Cleanup
4917 at fiber exit</a>
4918 </h6>
4919<p>
4920 When a fiber exits, the objects associated with each <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> instance
4921 are destroyed. By default, the object pointed to by a pointer <code class="computeroutput"><span class="identifier">p</span></code> is destroyed by invoking <code class="computeroutput"><span class="keyword">delete</span> <span class="identifier">p</span></code>,
4922 but this can be overridden for a specific instance of <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> by
4923 providing a cleanup routine <code class="computeroutput"><span class="identifier">func</span></code>
4924 to the constructor. In this case, the object is destroyed by invoking
4925 <code class="computeroutput"><span class="identifier">func</span><span class="special">(</span><span class="identifier">p</span><span class="special">)</span></code>.
4926 The cleanup functions are called in an unspecified order.
4927 </p>
4928<p>
4929 </p>
4930<h5>
4931<a name="class_fiber_specific_ptr_bridgehead"></a>
4932 <span><a name="class_fiber_specific_ptr"></a></span>
4933 <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr">Class
4934 <code class="computeroutput">fiber_specific_ptr</code></a>
4935</h5>
4936<p>
4937 </p>
4938<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">fss</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
4939
4940<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">&gt;</span>
4941<span class="keyword">class</span> <span class="identifier">fiber_specific_ptr</span> <span class="special">{</span>
4942<span class="keyword">public</span><span class="special">:</span>
4943 <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">element_type</span><span class="special">;</span>
4944
4945 <span class="identifier">fiber_specific_ptr</span><span class="special">();</span>
4946
4947 <span class="keyword">explicit</span> <span class="identifier">fiber_specific_ptr</span><span class="special">(</span> <span class="keyword">void</span><span class="special">(*</span><span class="identifier">fn</span><span class="special">)(</span><span class="identifier">T</span><span class="special">*)</span> <span class="special">);</span>
4948
4949 <span class="special">~</span><span class="identifier">fiber_specific_ptr</span><span class="special">();</span>
4950
4951 <span class="identifier">fiber_specific_ptr</span><span class="special">(</span> <span class="identifier">fiber_specific_ptr</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4952 <span class="identifier">fiber_specific_ptr</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">fiber_specific_ptr</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">=</span> <span class="keyword">delete</span><span class="special">;</span>
4953
4954 <span class="identifier">T</span> <span class="special">*</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
4955
4956 <span class="identifier">T</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">-&gt;()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
4957
4958 <span class="identifier">T</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
4959
4960 <span class="identifier">T</span> <span class="special">*</span> <span class="identifier">release</span><span class="special">();</span>
4961
4962 <span class="keyword">void</span> <span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="special">*);</span>
4963<span class="special">};</span>
4964</pre>
4965<h6>
4966<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.h2"></a>
4967 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.constructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls.constructor">Constructor</a>
4968 </h6>
4969<pre class="programlisting"><span class="identifier">fiber_specific_ptr</span><span class="special">();</span>
4970<span class="keyword">explicit</span> <span class="identifier">fiber_specific_ptr</span><span class="special">(</span> <span class="keyword">void</span><span class="special">(*</span><span class="identifier">fn</span><span class="special">)(</span><span class="identifier">T</span><span class="special">*)</span> <span class="special">);</span>
4971</pre>
4972<div class="variablelist">
4973<p class="title"><b></b></p>
4974<dl>
4975<dt><span class="term">Requires:</span></dt>
4976<dd><p>
4977 <code class="computeroutput"><span class="keyword">delete</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code> is well-formed; <code class="computeroutput"><span class="identifier">fn</span><span class="special">(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">())</span></code>
4978 does not throw
4979 </p></dd>
4980<dt><span class="term">Effects:</span></dt>
4981<dd><p>
4982 Construct a <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> object for
4983 storing a pointer to an object of type <code class="computeroutput"><span class="identifier">T</span></code>
4984 specific to each fiber. When <code class="computeroutput"><span class="identifier">reset</span><span class="special">()</span></code> is called, or the fiber exits,
4985 <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> calls <code class="computeroutput"><span class="identifier">fn</span><span class="special">(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">())</span></code>. If the no-arguments constructor
4986 is used, the default <code class="computeroutput"><span class="keyword">delete</span></code>-based
4987 cleanup function will be used to destroy the fiber-local objects.
4988 </p></dd>
4989<dt><span class="term">Throws:</span></dt>
4990<dd><p>
4991 <code class="computeroutput"><span class="identifier">fiber_error</span></code> if
4992 an error occurs.
4993 </p></dd>
4994</dl>
4995</div>
4996<h6>
4997<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.h3"></a>
4998 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.fls.destructor"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.fls.destructor">Destructor</a>
4999 </h6>
5000<pre class="programlisting"><span class="special">~</span><span class="identifier">fiber_specific_ptr</span><span class="special">();</span>
5001</pre>
5002<div class="variablelist">
5003<p class="title"><b></b></p>
5004<dl>
5005<dt><span class="term">Requires:</span></dt>
5006<dd><p>
5007 All the fiber specific instances associated to this <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a>
5008(except
5009 maybe the one associated to this fiber) must be nullptr.
5010 </p></dd>
5011<dt><span class="term">Effects:</span></dt>
5012<dd><p>
5013 Calls <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">reset</span><span class="special">()</span></code>
5014 to clean up the associated value for the current fiber, and destroys
5015 <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>.
5016 </p></dd>
5017<dt><span class="term">Remarks:</span></dt>
5018<dd><p>
5019 The requirement is an implementation restriction. If the destructor
5020 promised to delete instances for all fibers, the implementation
5021 would be forced to maintain a list of all the fibers having an
5022 associated specific ptr, which is against the goal of fiber specific
5023 data. In general, a <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> should
5024 outlive the fibers that use it.
5025 </p></dd>
5026</dl>
5027</div>
5028<div class="note"><table border="0" summary="Note">
5029<tr>
5030<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
5031<th align="left">Note</th>
5032</tr>
5033<tr><td align="left" valign="top"><p>
5034 Care needs to be taken to ensure that any fibers still running after
5035 an instance of <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> has been destroyed
5036 do not call any member functions on that instance.
5037 </p></td></tr>
5038</table></div>
5039<p>
5040 </p>
5041<h5>
5042<a name="fiber_specific_ptr_get_bridgehead"></a>
5043 <span><a name="fiber_specific_ptr_get"></a></span>
5044 <a class="link" href="pooled_fixedsize.html#fiber_specific_ptr_get">Member
5045 function <code class="computeroutput">get</code>()</a>
5046</h5>
5047<p>
5048 </p>
5049<pre class="programlisting"><span class="identifier">T</span> <span class="special">*</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
5050</pre>
5051<div class="variablelist">
5052<p class="title"><b></b></p>
5053<dl>
5054<dt><span class="term">Returns:</span></dt>
5055<dd><p>
5056 The pointer associated with the current fiber.
5057 </p></dd>
5058<dt><span class="term">Throws:</span></dt>
5059<dd><p>
5060 Nothing.
5061 </p></dd>
5062</dl>
5063</div>
5064<div class="note"><table border="0" summary="Note">
5065<tr>
5066<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
5067<th align="left">Note</th>
5068</tr>
5069<tr><td align="left" valign="top"><p>
5070 The initial value associated with an instance of <a class="link" href="pooled_fixedsize.html#class_fiber_specific_ptr"> <code class="computeroutput">fiber_specific_ptr</code></a> is
5071 <code class="computeroutput"><span class="keyword">nullptr</span></code> for each fiber.
5072 </p></td></tr>
5073</table></div>
5074<p>
5075 </p>
5076<h5>
5077<a name="fiber_specific_ptr_operator_arrow_bridgehead"></a>
5078 <span><a name="fiber_specific_ptr_operator_arrow"></a></span>
5079 <a class="link" href="pooled_fixedsize.html#fiber_specific_ptr_operator_arrow">Member
5080 function <code class="computeroutput">operator-&gt;</code>()</a>
5081</h5>
5082<p>
5083 </p>
5084<pre class="programlisting"><span class="identifier">T</span> <span class="special">*</span> <span class="keyword">operator</span><span class="special">-&gt;()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
5085</pre>
5086<div class="variablelist">
5087<p class="title"><b></b></p>
5088<dl>
5089<dt><span class="term">Requires:</span></dt>
5090<dd><p>
5091 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code>
5092 is not <code class="computeroutput"><span class="keyword">nullptr</span></code>.
5093 </p></dd>
5094<dt><span class="term">Returns:</span></dt>
5095<dd><p>
5096 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code>
5097 </p></dd>
5098<dt><span class="term">Throws:</span></dt>
5099<dd><p>
5100 Nothing.
5101 </p></dd>
5102</dl>
5103</div>
5104<p>
5105 </p>
5106<h5>
5107<a name="fiber_specific_ptr_operator_star_bridgehead"></a>
5108 <span><a name="fiber_specific_ptr_operator_star"></a></span>
5109 <a class="link" href="pooled_fixedsize.html#fiber_specific_ptr_operator_star">Member
5110 function <code class="computeroutput">operator*</code>()</a>
5111</h5>
5112<p>
5113 </p>
5114<pre class="programlisting"><span class="identifier">T</span> <span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span><span class="special">;</span>
5115</pre>
5116<div class="variablelist">
5117<p class="title"><b></b></p>
5118<dl>
5119<dt><span class="term">Requires:</span></dt>
5120<dd><p>
5121 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code>
5122 is not <code class="computeroutput"><span class="keyword">nullptr</span></code>.
5123 </p></dd>
5124<dt><span class="term">Returns:</span></dt>
5125<dd><p>
5126 <code class="computeroutput"><span class="special">*(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">())</span></code>
5127 </p></dd>
5128<dt><span class="term">Throws:</span></dt>
5129<dd><p>
5130 Nothing.
5131 </p></dd>
5132</dl>
5133</div>
5134<p>
5135 </p>
5136<h5>
5137<a name="fiber_specific_ptr_release_bridgehead"></a>
5138 <span><a name="fiber_specific_ptr_release"></a></span>
5139 <a class="link" href="pooled_fixedsize.html#fiber_specific_ptr_release">Member
5140 function <code class="computeroutput">release</code>()</a>
5141</h5>
5142<p>
5143 </p>
5144<pre class="programlisting"><span class="identifier">T</span> <span class="special">*</span> <span class="identifier">release</span><span class="special">();</span>
5145</pre>
5146<div class="variablelist">
5147<p class="title"><b></b></p>
5148<dl>
5149<dt><span class="term">Effects:</span></dt>
5150<dd><p>
5151 Return <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code>
5152 and store <code class="computeroutput"><span class="keyword">nullptr</span></code>
5153 as the pointer associated with the current fiber without invoking
5154 the cleanup function.
5155 </p></dd>
5156<dt><span class="term">Postcondition:</span></dt>
5157<dd><p>
5158 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()==</span><span class="keyword">nullptr</span></code>
5159 </p></dd>
5160<dt><span class="term">Throws:</span></dt>
5161<dd><p>
5162 Nothing.
5163 </p></dd>
5164</dl>
5165</div>
5166<p>
5167 </p>
5168<h5>
5169<a name="fiber_specific_ptr_reset_bridgehead"></a>
5170 <span><a name="fiber_specific_ptr_reset"></a></span>
5171 <a class="link" href="pooled_fixedsize.html#fiber_specific_ptr_reset">Member
5172 function <code class="computeroutput">reset</code>()</a>
5173</h5>
5174<p>
5175 </p>
5176<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="special">*</span> <span class="identifier">new_value</span><span class="special">);</span>
5177</pre>
5178<div class="variablelist">
5179<p class="title"><b></b></p>
5180<dl>
5181<dt><span class="term">Effects:</span></dt>
5182<dd><p>
5183 If <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()!=</span><span class="identifier">new_value</span></code> and <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code> is not <code class="computeroutput"><span class="keyword">nullptr</span></code>,
5184 invoke <code class="computeroutput"><span class="keyword">delete</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">fn</span><span class="special">(</span><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">())</span></code> as appropriate. Store <code class="computeroutput"><span class="identifier">new_value</span></code> as the pointer associated
5185 with the current fiber.
5186 </p></dd>
5187<dt><span class="term">Postcondition:</span></dt>
5188<dd><p>
5189 <code class="computeroutput"><span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">get</span><span class="special">()==</span><span class="identifier">new_value</span></code>
5190 </p></dd>
5191<dt><span class="term">Throws:</span></dt>
5192<dd><p>
5193 Exception raised during cleanup of previous value.
5194 </p></dd>
5195</dl>
5196</div>
5197</div>
5198<div class="section">
5199<div class="titlepage"><div><div><h5 class="title">
5200<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration"></a><a name="migration"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration" title="Migrating fibers between threads">Migrating
5201 fibers between threads</a>
5202</h5></div></div></div>
5203<h6>
5204<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.h0"></a>
5205 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.overview">Overview</a>
5206 </h6>
5207<p>
5208 Each fiber owns a stack and manages its execution state, including all
5209 registers and CPU flags, the instruction pointer and the stack pointer.
5210 That means, in general, a fiber is not bound to a specific thread.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f0" class="footnote">3</a>]</sup> <sup>,</sup><sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f1" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f1" class="footnote">4</a>]</sup>
5211 </p>
5212<p>
5213 Migrating a fiber from a logical CPU with heavy workload to another logical
5214 CPU with a lighter workload might speed up the overall execution. Note
5215 that in the case of NUMA-architectures, it is not always advisable to
5216 migrate data between threads. Suppose fiber <span class="emphasis"><em>f</em></span> is
5217 running on logical CPU <span class="emphasis"><em>cpu0</em></span> which belongs to NUMA
5218 node <span class="emphasis"><em>node0</em></span>. The data of <span class="emphasis"><em>f</em></span> are
5219 allocated on the physical memory located at <span class="emphasis"><em>node0</em></span>.
5220 Migrating the fiber from <span class="emphasis"><em>cpu0</em></span> to another logical
5221 CPU <span class="emphasis"><em>cpuX</em></span> which is part of a different NUMA node
5222 <span class="emphasis"><em>nodeX</em></span> might reduce the performance of the application
5223 due to increased latency of memory access.
5224 </p>
5225<p>
5226 Only fibers that are contained in <a class="link" href="../../scheduling.html#class_sched_algorithm"> <code class="computeroutput">sched_algorithm</code></a>'s
5227 ready queue can migrate between threads. You cannot migrate a running
5228 fiber, nor one that is <a class="link" href="../../overview.html#blocking"><span class="emphasis"><em>blocked</em></span></a>.
5229 </p>
5230<p>
5231 In<span class="bold"><strong>Boost.Fiber</strong></span> a fiber is migrated by
5232 invoking <a class="link" href="../../scheduling.html#context_migrate"> <code class="computeroutput">context::migrate()</code></a> on the <a class="link" href="../../scheduling.html#class_context"> <code class="computeroutput">context</code></a> instance
5233 for a fiber already associated with the destination thread, passing the
5234 <code class="computeroutput"><span class="identifier">context</span></code> for the fiber
5235 to be migrated.
5236 </p>
5237<h6>
5238<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.h1"></a>
5239 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.example_of_work_sharing"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.example_of_work_sharing">Example
5240 of work sharing</a>
5241 </h6>
5242<p>
5243 In the example <a href="../../../../../examples/work_sharing.cpp" target="_top">work_sharing.cpp</a>
5244 multiple worker fibers are created on the main thread. Each fiber gets
5245 a character as parameter at construction. This character is printed out
5246 ten times. Between each iteration the fiber calls <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_yield"> <code class="computeroutput">this_fiber::yield()</code></a>.
5247 That puts the fiber in the ready queue of the fiber-scheduler <span class="emphasis"><em>shared_ready_queue</em></span>,
5248 running in the current thread. The next fiber ready to be executed is
5249 dequeued from the shared ready queue and resumed by <span class="emphasis"><em>shared_ready_queue</em></span>
5250 running on <span class="emphasis"><em>any participating thread</em></span>.
5251 </p>
5252<p>
5253 All instances of <span class="emphasis"><em>shared_ready_queue</em></span> share one global
5254 concurrent queue, used as ready queue. This mechanism shares all worker
5255 fibers between all instances of <span class="emphasis"><em>shared_ready_queue</em></span>,
5256 thus between all participating threads.
5257 </p>
5258<h6>
5259<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.h2"></a>
5260 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.setup_of_threads_and_fibers"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.setup_of_threads_and_fibers">Setup
5261 of threads and fibers</a>
5262 </h6>
5263<p>
5264 In <code class="computeroutput"><span class="identifier">main</span><span class="special">()</span></code>
5265 the fiber-scheduler is installed and the worker fibers and the threads
5266 are launched.
5267 </p>
5268<p>
5269</p>
5270<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">use_scheduling_algorithm</span><span class="special">&lt;</span> <span class="identifier">shared_ready_queue</span> <span class="special">&gt;();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c0" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c1"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
5271
5272<span class="keyword">for</span> <span class="special">(</span> <span class="keyword">char</span> <span class="identifier">c</span> <span class="special">:</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">(</span><span class="string">"abcdefghijklmnopqrstuvwxyz"</span><span class="special">))</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c2" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c3"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
5273 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">([</span><span class="identifier">c</span><span class="special">](){</span> <span class="identifier">whatevah</span><span class="special">(</span> <span class="identifier">c</span><span class="special">);</span> <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
5274 <span class="special">++</span><span class="identifier">fiber_count</span><span class="special">;</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c4" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c5"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
5275<span class="special">}</span>
5276<span class="identifier">barrier</span> <span class="identifier">b</span><span class="special">(</span> <span class="number">4</span><span class="special">);</span>
5277<span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="identifier">threads</span><span class="special">[]</span> <span class="special">=</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c6" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c7"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
5278 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">),</span>
5279 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">),</span>
5280 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">(</span> <span class="identifier">thread</span><span class="special">,</span> <span class="special">&amp;</span> <span class="identifier">b</span><span class="special">)</span>
5281<span class="special">};</span>
5282<span class="identifier">b</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c8" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c9"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a>
5283<span class="special">{</span>
5284 <span class="identifier">lock_t</span><a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c10" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c11"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
5285 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[](){</span> <span class="keyword">return</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">;</span> <span class="special">}</span> <span class="special">);</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c12" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c13"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a>
5286<span class="special">}</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c14" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c15"><img src="../../../../../../../doc/src/images/callouts/8.png" alt="8" border="0"></a>
5287<span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">);</span>
5288<span class="keyword">for</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span> <span class="special">&amp;</span> <span class="identifier">t</span> <span class="special">:</span> <span class="identifier">threads</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c16" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c17"><img src="../../../../../../../doc/src/images/callouts/9.png" alt="9" border="0"></a>
5289 <span class="identifier">t</span><span class="special">.</span><span class="identifier">join</span><span class="special">();</span>
5290<span class="special">}</span>
5291</pre>
5292<p>
5293 </p>
5294<div class="calloutlist"><table border="0" summary="Callout list">
5295<tr>
5296<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c1"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c0"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
5297<td valign="top" align="left"><p>
5298 Install the scheduling algorithm <code class="computeroutput"><span class="identifier">shared_ready_queue</span></code>
5299 in the main thread too, so each new fiber gets launched into the
5300 shared pool.
5301 </p></td>
5302</tr>
5303<tr>
5304<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c3"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c2"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
5305<td valign="top" align="left"><p>
5306 Launch a number of worker fibers; each worker fiber picks up a character
5307 that is passed as parameter to fiber-function <code class="computeroutput"><span class="identifier">whatevah</span></code>.
5308 Each worker fiber gets detached.
5309 </p></td>
5310</tr>
5311<tr>
5312<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c5"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c4"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
5313<td valign="top" align="left"><p>
5314 Increment fiber counter for each new fiber.
5315 </p></td>
5316</tr>
5317<tr>
5318<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c7"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c6"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
5319<td valign="top" align="left"><p>
5320 Launch a couple of threads that join the work sharing.
5321 </p></td>
5322</tr>
5323<tr>
5324<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c9"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c8"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a> </p></td>
5325<td valign="top" align="left"><p>
5326 sync with other threads: allow them to start processing
5327 </p></td>
5328</tr>
5329<tr>
5330<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c11"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c10"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> </p></td>
5331<td valign="top" align="left"><p>
5332 <code class="computeroutput"><span class="identifier">lock_t</span></code> is typedef'ed
5333 as <a href="http://en.cppreference.com/w/cpp/thread/unique_lock" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span></code></a>&lt; <a href="http://en.cppreference.com/w/cpp/thread/mutex" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span></code></a> &gt;
5334 </p></td>
5335</tr>
5336<tr>
5337<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c13"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c12"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a> </p></td>
5338<td valign="top" align="left"><p>
5339 Suspend main fiber and resume worker fibers in the meanwhile. Main
5340 fiber gets resumed (e.g returns from <code class="computeroutput"><span class="identifier">condition_variable_any</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>) if all worker fibers are complete.
5341 </p></td>
5342</tr>
5343<tr>
5344<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c15"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c14"><img src="../../../../../../../doc/src/images/callouts/8.png" alt="8" border="0"></a> </p></td>
5345<td valign="top" align="left"><p>
5346 Releasing lock of mtx_count is required before joining the threads,
5347 othwerwise the other threads would be blocked inside condition_variable::wait()
5348 and would never return (deadlock).
5349 </p></td>
5350</tr>
5351<tr>
5352<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c17"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c16"><img src="../../../../../../../doc/src/images/callouts/9.png" alt="9" border="0"></a> </p></td>
5353<td valign="top" align="left"><p>
5354 wait for threads to terminate
5355 </p></td>
5356</tr>
5357</table></div>
5358<p>
5359 The start of the threads is synchronized with a barrier. The main fiber
5360 of each thread (including main thread) is suspended until all worker
5361 fibers are complete. When the main fiber returns from <a class="link" href="pooled_fixedsize.html#condition_variable_wait"> <code class="computeroutput">condition_variable::wait()</code></a>,
5362 the thread terminates: the main thread joins all other threads.
5363 </p>
5364<p>
5365</p>
5366<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">thread</span><span class="special">(</span> <span class="identifier">barrier</span> <span class="special">*</span> <span class="identifier">b</span><span class="special">)</span> <span class="special">{</span>
5367 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
5368 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"thread started "</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
5369 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
5370 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">use_scheduling_algorithm</span><span class="special">&lt;</span> <span class="identifier">shared_ready_queue</span> <span class="special">&gt;();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c18" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c19"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
5371 <span class="identifier">b</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c20" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c21"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
5372 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
5373 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[](){</span> <span class="keyword">return</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">;</span> <span class="special">}</span> <span class="special">);</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c22" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c23"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
5374 <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">fiber_count</span><span class="special">);</span>
5375<span class="special">}</span>
5376</pre>
5377<p>
5378 </p>
5379<div class="calloutlist"><table border="0" summary="Callout list">
5380<tr>
5381<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c19"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c18"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
5382<td valign="top" align="left"><p>
5383 Install the scheduling algorithm <code class="computeroutput"><span class="identifier">shared_ready_queue</span></code>
5384 in order to join the work sharing.
5385 </p></td>
5386</tr>
5387<tr>
5388<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c21"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c20"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
5389<td valign="top" align="left"><p>
5390 sync with other threads: allow them to start processing
5391 </p></td>
5392</tr>
5393<tr>
5394<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c23"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c22"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
5395<td valign="top" align="left"><p>
5396 Suspend main fiber and resume worker fibers in the meanwhile. Main
5397 fiber gets resumed (e.g returns from <code class="computeroutput"><span class="identifier">condition_variable_any</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>) if all worker fibers are complete.
5398 </p></td>
5399</tr>
5400</table></div>
5401<p>
5402 Each worker fiber executes function <code class="computeroutput"><span class="identifier">whatevah</span><span class="special">()</span></code> with character <code class="computeroutput"><span class="identifier">me</span></code>
5403 as parameter. The fiber yields in a loop and prints out a message if
5404 it was migrated to another thread.
5405 </p>
5406<p>
5407</p>
5408<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">whatevah</span><span class="special">(</span> <span class="keyword">char</span> <span class="identifier">me</span><span class="special">)</span> <span class="special">{</span>
5409 <span class="keyword">try</span> <span class="special">{</span>
5410 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">id</span> <span class="identifier">my_thread</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c24" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c25"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
5411 <span class="special">{</span>
5412 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
5413 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"fiber "</span> <span class="special">&lt;&lt;</span> <span class="identifier">me</span> <span class="special">&lt;&lt;</span> <span class="string">" started on thread "</span> <span class="special">&lt;&lt;</span> <span class="identifier">my_thread</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
5414 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
5415 <span class="special">}</span>
5416 <span class="keyword">for</span> <span class="special">(</span> <span class="keyword">unsigned</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="number">10</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c26" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c27"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
5417 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">yield</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c28" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c29"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
5418 <span class="identifier">std</span><span class="special">::</span><span class="identifier">thread</span><span class="special">::</span><span class="identifier">id</span> <span class="identifier">new_thread</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">this_thread</span><span class="special">::</span><span class="identifier">get_id</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c30" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c31"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
5419 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">new_thread</span> <span class="special">!=</span> <span class="identifier">my_thread</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c32" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c33"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a>
5420 <span class="identifier">my_thread</span> <span class="special">=</span> <span class="identifier">new_thread</span><span class="special">;</span>
5421 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">buffer</span><span class="special">;</span>
5422 <span class="identifier">buffer</span> <span class="special">&lt;&lt;</span> <span class="string">"fiber "</span> <span class="special">&lt;&lt;</span> <span class="identifier">me</span> <span class="special">&lt;&lt;</span> <span class="string">" switched to thread "</span> <span class="special">&lt;&lt;</span> <span class="identifier">my_thread</span> <span class="special">&lt;&lt;</span> <span class="char">'\n'</span><span class="special">;</span>
5423 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">buffer</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">flush</span><span class="special">;</span>
5424 <span class="special">}</span>
5425 <span class="special">}</span>
5426 <span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span> <span class="special">...</span> <span class="special">)</span> <span class="special">{</span>
5427 <span class="special">}</span>
5428 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_count</span><span class="special">);</span>
5429 <span class="keyword">if</span> <span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="special">--</span><span class="identifier">fiber_count</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c34" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c35"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a>
5430 <span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
5431 <span class="identifier">cnd_count</span><span class="special">.</span><span class="identifier">notify_all</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c36" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c37"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a>
5432 <span class="special">}</span>
5433<span class="special">}</span>
5434</pre>
5435<p>
5436 </p>
5437<div class="calloutlist"><table border="0" summary="Callout list">
5438<tr>
5439<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c25"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c24"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
5440<td valign="top" align="left"><p>
5441 get ID of initial thread
5442 </p></td>
5443</tr>
5444<tr>
5445<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c27"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c26"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
5446<td valign="top" align="left"><p>
5447 loop ten times
5448 </p></td>
5449</tr>
5450<tr>
5451<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c29"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c28"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
5452<td valign="top" align="left"><p>
5453 yield to other fibers
5454 </p></td>
5455</tr>
5456<tr>
5457<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c31"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c30"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
5458<td valign="top" align="left"><p>
5459 get ID of current thread
5460 </p></td>
5461</tr>
5462<tr>
5463<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c33"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c32"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a> </p></td>
5464<td valign="top" align="left"><p>
5465 test if fiber was migrated to another thread
5466 </p></td>
5467</tr>
5468<tr>
5469<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c35"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c34"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> </p></td>
5470<td valign="top" align="left"><p>
5471 Decrement fiber counter for each completed fiber.
5472 </p></td>
5473</tr>
5474<tr>
5475<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c37"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c36"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a> </p></td>
5476<td valign="top" align="left"><p>
5477 Notify all fibers waiting on <code class="computeroutput"><span class="identifier">cnd_count</span></code>.
5478 </p></td>
5479</tr>
5480</table></div>
5481<h6>
5482<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.h3"></a>
5483 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.scheduling_fibers"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.scheduling_fibers">Scheduling
5484 fibers</a>
5485 </h6>
5486<p>
5487 The fiber scheduler <code class="computeroutput"><span class="identifier">shared_ready_queue</span></code>
5488 is like <code class="computeroutput"><span class="identifier">round_robin</span></code>,
5489 except that it shares a common ready queue among all participating threads.
5490 A thread participates in this pool by executing <a class="link" href="../../fiber_mgmt/fiber.html#use_scheduling_algorithm"> <code class="computeroutput">use_scheduling_algorithm()</code></a>
5491before
5492 any other <span class="bold"><strong>Boost.Fiber</strong></span> operation.
5493 </p>
5494<p>
5495 The important point about the ready queue is that it's a class static,
5496 common to all instances of shared_ready_queue. Fibers that are enqueued
5497 via <a class="link" href="../../scheduling.html#sched_algorithm_awakened"> <code class="computeroutput">sched_algorithm::awakened()</code></a> (fibers that are
5498 ready to be resumed) are thus available to all threads. It is required
5499 to reserve a separate, scheduler-specific queue for the thread's main
5500 fiber and dispatcher fibers: these may <span class="emphasis"><em>not</em></span> be shared
5501 between threads! When we're passed either of these fibers, push it there
5502 instead of in the shared queue: it would be Bad News for thread B to
5503 retrieve and attempt to execute thread A's main fiber.
5504 </p>
5505<p>
5506</p>
5507<pre class="programlisting"><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">awakened</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">{</span>
5508 <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="keyword">nullptr</span> <span class="special">!=</span> <span class="identifier">ctx</span><span class="special">);</span>
5509
5510 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">ctx</span><span class="special">-&gt;</span><span class="identifier">is_context</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">pinned_context</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c38" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c39"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
5511 <span class="identifier">local_queue_</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">);</span>
5512 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
5513 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span><span class="identifier">rqueue_mtx_</span><span class="special">);</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c40" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c41"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
5514 <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">);</span>
5515 <span class="special">}</span>
5516<span class="special">}</span>
5517</pre>
5518<p>
5519 </p>
5520<div class="calloutlist"><table border="0" summary="Callout list">
5521<tr>
5522<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c39"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c38"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
5523<td valign="top" align="left"><p>
5524 recognize when we're passed this thread's main fiber (or an implicit
5525 library helper fiber): never put those on the shared queue
5526 </p></td>
5527</tr>
5528<tr>
5529<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c41"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c40"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
5530<td valign="top" align="left"><p>
5531 worker fiber, enqueue on shared queue
5532 </p></td>
5533</tr>
5534</table></div>
5535<p>
5536 When <a class="link" href="../../scheduling.html#sched_algorithm_pick_next"> <code class="computeroutput">sched_algorithm::pick_next()</code></a> gets called
5537 inside one thread, a fiber is dequeued from <span class="emphasis"><em>rqueue_</em></span>
5538 and will be resumed in that thread.
5539 </p>
5540<p>
5541</p>
5542<pre class="programlisting"><span class="keyword">virtual</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">pick_next</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{</span>
5543 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">(</span> <span class="keyword">nullptr</span><span class="special">);</span>
5544 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">(</span><span class="identifier">rqueue_mtx_</span><span class="special">);</span>
5545 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c42" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c43"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
5546 <span class="identifier">ctx</span> <span class="special">=</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">front</span><span class="special">();</span>
5547 <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">pop</span><span class="special">();</span>
5548 <span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
5549 <span class="identifier">BOOST_ASSERT</span><span class="special">(</span> <span class="keyword">nullptr</span> <span class="special">!=</span> <span class="identifier">ctx</span><span class="special">);</span>
5550 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">active</span><span class="special">()-&gt;</span><span class="identifier">migrate</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">);</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c44" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c45"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
5551 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
5552 <span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
5553 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">local_queue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c46" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c47"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
5554 <span class="identifier">ctx</span> <span class="special">=</span> <span class="identifier">local_queue_</span><span class="special">.</span><span class="identifier">front</span><span class="special">();</span>
5555 <span class="identifier">local_queue_</span><span class="special">.</span><span class="identifier">pop</span><span class="special">();</span>
5556 <span class="special">}</span>
5557 <span class="special">}</span>
5558 <span class="keyword">return</span> <span class="identifier">ctx</span><span class="special">;</span>
5559<span class="special">}</span>
5560</pre>
5561<p>
5562 </p>
5563<div class="calloutlist"><table border="0" summary="Callout list">
5564<tr>
5565<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c43"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c42"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
5566<td valign="top" align="left"><p>
5567 pop an item from the ready queue
5568 </p></td>
5569</tr>
5570<tr>
5571<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c45"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c44"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
5572<td valign="top" align="left"><p>
5573 attach context to current scheduler via the active fiber of this
5574 thread; benign if the fiber already belongs to this thread
5575 </p></td>
5576</tr>
5577<tr>
5578<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c47"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.c46"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
5579<td valign="top" align="left"><p>
5580 nothing in the ready queue, return main or dispatcher fiber
5581 </p></td>
5582</tr>
5583</table></div>
5584<p>
5585 The source code above is found in <a href="../../../../../examples/work_sharing.cpp" target="_top">work_sharing.cpp</a>.
5586 </p>
5587</div>
5588<div class="section">
5589<div class="titlepage"><div><div><h5 class="title">
5590<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks"></a><a name="callbacks"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks" title="Integrating Fibers with Asynchronous Callbacks">Integrating
5591 Fibers with Asynchronous Callbacks</a>
5592</h5></div></div></div>
5593<h6>
5594<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h0"></a>
5595 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.overview">Overview</a>
5596 </h6>
5597<p>
5598 One of the primary benefits of <span class="bold"><strong>Boost.Fiber</strong></span>
5599 is the ability to use asynchronous operations for efficiency, while at
5600 the same time structuring the calling code <span class="emphasis"><em>as if</em></span>
5601 the operations were synchronous. Asynchronous operations provide completion
5602 notification in a variety of ways, but most involve a callback function
5603 of some kind. This section discusses tactics for interfacing <span class="bold"><strong>Boost.Fiber</strong></span> with an arbitrary async operation.
5604 </p>
5605<p>
5606 For purposes of illustration, consider the following hypothetical API:
5607 </p>
5608<p>
5609</p>
5610<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">AsyncAPI</span> <span class="special">{</span>
5611<span class="keyword">public</span><span class="special">:</span>
5612 <span class="comment">// constructor acquires some resource that can be read and written</span>
5613 <span class="identifier">AsyncAPI</span><span class="special">();</span>
5614
5615 <span class="comment">// callbacks accept an int error code; 0 == success</span>
5616 <span class="keyword">typedef</span> <span class="keyword">int</span> <span class="identifier">errorcode</span><span class="special">;</span>
5617
5618 <span class="comment">// write callback only needs to indicate success or failure</span>
5619 <span class="keyword">void</span> <span class="identifier">init_write</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">,</span>
5620 <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="keyword">void</span><span class="special">(</span> <span class="identifier">errorcode</span><span class="special">)</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">callback</span><span class="special">);</span>
5621
5622 <span class="comment">// read callback needs to accept both errorcode and data</span>
5623 <span class="keyword">void</span> <span class="identifier">init_read</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span> <span class="keyword">void</span><span class="special">(</span> <span class="identifier">errorcode</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;)</span> <span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;);</span>
5624
5625 <span class="comment">// ... other operations ...</span>
5626<span class="special">};</span>
5627</pre>
5628<p>
5629 </p>
5630<p>
5631 The significant points about each of <code class="computeroutput"><span class="identifier">init_write</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">init_read</span><span class="special">()</span></code> are:
5632 </p>
5633<div class="itemizedlist"><ul class="itemizedlist" type="disc">
5634<li class="listitem">
5635 The <code class="computeroutput"><span class="identifier">AsyncAPI</span></code> method
5636 only initiates the operation. It returns immediately, while the requested
5637 operation is still pending.
5638 </li>
5639<li class="listitem">
5640 The method accepts a callback. When the operation completes, the
5641 callback is called with relevant parameters (error code, data if
5642 applicable).
5643 </li>
5644</ul></div>
5645<p>
5646 We would like to wrap these asynchronous methods in functions that appear
5647 synchronous by blocking the calling fiber until the operation completes.
5648 This lets us use the wrapper function's return value to deliver relevant
5649 data.
5650 </p>
5651<div class="tip"><table border="0" summary="Tip">
5652<tr>
5653<td rowspan="2" align="center" valign="top" width="25"><img alt="[Tip]" src="../../../../../../../doc/src/images/tip.png"></td>
5654<th align="left">Tip</th>
5655</tr>
5656<tr><td align="left" valign="top"><p>
5657 <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> and <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> are your
5658 friends here.
5659 </p></td></tr>
5660</table></div>
5661<h6>
5662<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h1"></a>
5663 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.return_errorcode"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.return_errorcode">Return
5664 Errorcode</a>
5665 </h6>
5666<p>
5667 The <code class="computeroutput"><span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">init_write</span><span class="special">()</span></code>
5668 callback passes only an <code class="computeroutput"><span class="identifier">errorcode</span></code>.
5669 If we simply want the blocking wrapper to return that <code class="computeroutput"><span class="identifier">errorcode</span></code>,
5670 this is an extremely straightforward use of <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a> and
5671 <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a>:
5672 </p>
5673<p>
5674</p>
5675<pre class="programlisting"><span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">write_ec</span><span class="special">(</span> <span class="identifier">AsyncAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
5676 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="special">&gt;</span> <span class="identifier">promise</span><span class="special">;</span>
5677 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="special">&gt;</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">promise</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">()</span> <span class="special">);</span>
5678 <span class="comment">// In general, even though we block waiting for future::get() and therefore</span>
5679 <span class="comment">// won't destroy 'promise' until promise::set_value() has been called, we</span>
5680 <span class="comment">// are advised that with threads it's possible for ~promise() to be</span>
5681 <span class="comment">// entered before promise::set_value() has returned. While that shouldn't</span>
5682 <span class="comment">// happen with fibers::promise, a robust way to deal with the lifespan</span>
5683 <span class="comment">// issue is to bind 'promise' into our lambda. Since promise is move-only,</span>
5684 <span class="comment">// use initialization capture.</span>
5685 <span class="identifier">api</span><span class="special">.</span><span class="identifier">init_write</span><span class="special">(</span>
5686 <span class="identifier">data</span><span class="special">,</span>
5687 <span class="special">[&amp;</span><span class="identifier">promise</span><span class="special">](</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span><span class="special">)</span> <span class="keyword">mutable</span> <span class="special">{</span>
5688 <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">ec</span><span class="special">);</span>
5689 <span class="special">});</span>
5690 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
5691<span class="special">}</span>
5692</pre>
5693<p>
5694 </p>
5695<p>
5696 All we have to do is:
5697 </p>
5698<div class="orderedlist"><ol class="orderedlist" type="1">
5699<li class="listitem">
5700 Instantiate a <code class="computeroutput"><span class="identifier">promise</span><span class="special">&lt;&gt;</span></code> of correct type.
5701 </li>
5702<li class="listitem">
5703 Obtain its <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>.
5704 </li>
5705<li class="listitem">
5706 Arrange for the callback to call <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a>.
5707 </li>
5708<li class="listitem">
5709 Block on <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a>.
5710 </li>
5711</ol></div>
5712<div class="note"><table border="0" summary="Note">
5713<tr>
5714<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
5715<th align="left">Note</th>
5716</tr>
5717<tr><td align="left" valign="top"><p>
5718 This tactic for resuming a pending fiber works even if the callback
5719 is called on a different thread than the one on which the initiating
5720 fiber is running. In fact, <a href="../../../../../examples/adapt_callbacks.cpp" target="_top">the
5721 example program's</a> dummy <code class="computeroutput"><span class="identifier">AsyncAPI</span></code>
5722 implementation illustrates that: it simulates async I/O by launching
5723 a new thread that sleeps briefly and then calls the relevant callback.
5724 </p></td></tr>
5725</table></div>
5726<h6>
5727<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h2"></a>
5728 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.success_or_exception"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.success_or_exception">Success
5729 or Exception</a>
5730 </h6>
5731<p>
5732 A wrapper more aligned with modern C++ practice would use an exception,
5733 rather than an <code class="computeroutput"><span class="identifier">errorcode</span></code>,
5734 to communicate failure to its caller. This is straightforward to code
5735 in terms of <code class="computeroutput"><span class="identifier">write_ec</span><span class="special">()</span></code>:
5736 </p>
5737<p>
5738</p>
5739<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">write</span><span class="special">(</span> <span class="identifier">AsyncAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
5740 <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span> <span class="special">=</span> <span class="identifier">write_ec</span><span class="special">(</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">data</span><span class="special">);</span>
5741 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
5742 <span class="keyword">throw</span> <span class="identifier">make_exception</span><span class="special">(</span><span class="string">"write"</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
5743 <span class="special">}</span>
5744<span class="special">}</span>
5745</pre>
5746<p>
5747 </p>
5748<p>
5749 The point is that since each fiber has its own stack, you need not repeat
5750 messy boilerplate: normal encapsulation works.
5751 </p>
5752<h6>
5753<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h3"></a>
5754 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.return_errorcode_or_data"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.return_errorcode_or_data">Return
5755 Errorcode or Data</a>
5756 </h6>
5757<p>
5758 Things get a bit more interesting when the async operation's callback
5759 passes multiple data items of interest. One approach would be to use
5760 <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;&gt;</span></code>
5761 to capture both:
5762 </p>
5763<p>
5764</p>
5765<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">read_ec</span><span class="special">(</span> <span class="identifier">AsyncAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">)</span> <span class="special">{</span>
5766 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">result_pair</span><span class="special">;</span>
5767 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">result_pair</span> <span class="special">&gt;</span> <span class="identifier">promise</span><span class="special">;</span>
5768 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">result_pair</span> <span class="special">&gt;</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">promise</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">()</span> <span class="special">);</span>
5769 <span class="comment">// We promise that both 'promise' and 'future' will survive until our</span>
5770 <span class="comment">// lambda has been called.</span>
5771 <span class="identifier">api</span><span class="special">.</span><span class="identifier">init_read</span><span class="special">([&amp;</span><span class="identifier">promise</span><span class="special">](</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="keyword">mutable</span> <span class="special">{</span>
5772 <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">result_pair</span><span class="special">(</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">);</span>
5773 <span class="special">});</span>
5774 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
5775<span class="special">}</span>
5776</pre>
5777<p>
5778 </p>
5779<p>
5780 Once you bundle the interesting data in <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special">&lt;&gt;</span></code>, the code is effectively identical
5781 to <code class="computeroutput"><span class="identifier">write_ec</span><span class="special">()</span></code>.
5782 You can call it like this:
5783 </p>
5784<p>
5785</p>
5786<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">read_ec</span><span class="special">(</span> <span class="identifier">api</span><span class="special">);</span>
5787</pre>
5788<p>
5789 </p>
5790<a name="Data_or_Exception"></a><h6>
5791<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h4"></a>
5792 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.data_or_exception"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.data_or_exception">Data
5793 or Exception</a>
5794 </h6>
5795<p>
5796 But a more natural API for a function that obtains data is to return
5797 only the data on success, throwing an exception on error.
5798 </p>
5799<p>
5800 As with <code class="computeroutput"><span class="identifier">write</span><span class="special">()</span></code>
5801 above, it's certainly possible to code a <code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code> wrapper in terms of <code class="computeroutput"><span class="identifier">read_ec</span><span class="special">()</span></code>. But since a given application is unlikely
5802 to need both, let's code <code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code> from scratch, leveraging <a class="link" href="pooled_fixedsize.html#promise_set_exception"> <code class="computeroutput">promise::set_exception()</code></a>:
5803 </p>
5804<p>
5805</p>
5806<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">read</span><span class="special">(</span> <span class="identifier">AsyncAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">)</span> <span class="special">{</span>
5807 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">promise</span><span class="special">;</span>
5808 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">promise</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">()</span> <span class="special">);</span>
5809 <span class="comment">// Both 'promise' and 'future' will survive until our lambda has been</span>
5810 <span class="comment">// called.</span>
5811 <span class="identifier">api</span><span class="special">.</span><span class="identifier">init_read</span><span class="special">([&amp;</span><span class="identifier">promise</span><span class="special">](</span> <span class="identifier">AsyncAPI</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="keyword">mutable</span> <span class="special">{</span>
5812 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
5813 <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">data</span><span class="special">);</span>
5814 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
5815 <span class="identifier">promise</span><span class="special">.</span><span class="identifier">set_exception</span><span class="special">(</span>
5816 <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_exception_ptr</span><span class="special">(</span>
5817 <span class="identifier">make_exception</span><span class="special">(</span><span class="string">"read"</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">)</span> <span class="special">);</span>
5818 <span class="special">}</span>
5819 <span class="special">});</span>
5820 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
5821<span class="special">}</span>
5822</pre>
5823<p>
5824 </p>
5825<p>
5826 <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> will do the right thing, either returning <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code> or throwing an exception.
5827 </p>
5828<h6>
5829<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h5"></a>
5830 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.success_error_virtual_methods"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.success_error_virtual_methods">Success/Error
5831 Virtual Methods</a>
5832 </h6>
5833<p>
5834 One classic approach to completion notification is to define an abstract
5835 base class with <code class="computeroutput"><span class="identifier">success</span><span class="special">()</span></code> and <code class="computeroutput"><span class="identifier">error</span><span class="special">()</span></code> methods. Code wishing to perform async
5836 I/O must derive a subclass, override each of these methods and pass the
5837 async operation a pointer to a subclass instance. The abstract base class
5838 might look like this:
5839 </p>
5840<p>
5841</p>
5842<pre class="programlisting"><span class="comment">// every async operation receives a subclass instance of this abstract base</span>
5843<span class="comment">// class through which to communicate its result</span>
5844<span class="keyword">struct</span> <span class="identifier">Response</span> <span class="special">{</span>
5845 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">Response</span> <span class="special">&gt;</span> <span class="identifier">ptr</span><span class="special">;</span>
5846
5847 <span class="comment">// called if the operation succeeds</span>
5848 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">success</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
5849
5850 <span class="comment">// called if the operation fails</span>
5851 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">error</span><span class="special">(</span> <span class="identifier">AsyncAPIBase</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
5852<span class="special">};</span>
5853</pre>
5854<p>
5855 </p>
5856<p>
5857 Now the <code class="computeroutput"><span class="identifier">AsyncAPI</span></code> operation
5858 might look more like this:
5859 </p>
5860<p>
5861</p>
5862<pre class="programlisting"><span class="comment">// derive Response subclass, instantiate, pass Response::ptr</span>
5863<span class="keyword">void</span> <span class="identifier">init_read</span><span class="special">(</span> <span class="identifier">Response</span><span class="special">::</span><span class="identifier">ptr</span><span class="special">);</span>
5864</pre>
5865<p>
5866 </p>
5867<p>
5868 We can address this by writing a one-size-fits-all <code class="computeroutput"><span class="identifier">PromiseResponse</span></code>:
5869 </p>
5870<p>
5871</p>
5872<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">PromiseResponse</span><span class="special">:</span> <span class="keyword">public</span> <span class="identifier">Response</span> <span class="special">{</span>
5873<span class="keyword">public</span><span class="special">:</span>
5874 <span class="comment">// called if the operation succeeds</span>
5875 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">success</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">)</span> <span class="special">{</span>
5876 <span class="identifier">promise_</span><span class="special">.</span><span class="identifier">set_value</span><span class="special">(</span> <span class="identifier">data</span><span class="special">);</span>
5877 <span class="special">}</span>
5878
5879 <span class="comment">// called if the operation fails</span>
5880 <span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">error</span><span class="special">(</span> <span class="identifier">AsyncAPIBase</span><span class="special">::</span><span class="identifier">errorcode</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
5881 <span class="identifier">promise_</span><span class="special">.</span><span class="identifier">set_exception</span><span class="special">(</span>
5882 <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_exception_ptr</span><span class="special">(</span>
5883 <span class="identifier">make_exception</span><span class="special">(</span><span class="string">"read"</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">)</span> <span class="special">);</span>
5884 <span class="special">}</span>
5885
5886 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">get_future</span><span class="special">()</span> <span class="special">{</span>
5887 <span class="keyword">return</span> <span class="identifier">promise_</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">();</span>
5888 <span class="special">}</span>
5889
5890<span class="keyword">private</span><span class="special">:</span>
5891 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">promise</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">promise_</span><span class="special">;</span>
5892<span class="special">};</span>
5893</pre>
5894<p>
5895 </p>
5896<p>
5897 Now we can simply obtain the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> from that <code class="computeroutput"><span class="identifier">PromiseResponse</span></code>
5898 and wait on its <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code>:
5899 </p>
5900<p>
5901</p>
5902<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">read</span><span class="special">(</span> <span class="identifier">AsyncAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">)</span> <span class="special">{</span>
5903 <span class="comment">// Because init_read() requires a shared_ptr, we must allocate our</span>
5904 <span class="comment">// ResponsePromise on the heap, even though we know its lifespan.</span>
5905 <span class="keyword">auto</span> <span class="identifier">promisep</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">PromiseResponse</span> <span class="special">&gt;()</span> <span class="special">);</span>
5906 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">promisep</span><span class="special">-&gt;</span><span class="identifier">get_future</span><span class="special">()</span> <span class="special">);</span>
5907 <span class="comment">// Both 'promisep' and 'future' will survive until our lambda has been</span>
5908 <span class="comment">// called.</span>
5909 <span class="identifier">api</span><span class="special">.</span><span class="identifier">init_read</span><span class="special">(</span> <span class="identifier">promisep</span><span class="special">);</span>
5910 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
5911<span class="special">}</span>
5912</pre>
5913<p>
5914 </p>
5915<p>
5916 The source code above is found in <a href="../../../../../examples/adapt_callbacks.cpp" target="_top">adapt_callbacks.cpp</a>
5917 and <a href="../../../../../examples/adapt_method_calls.cpp" target="_top">adapt_method_calls.cpp</a>.
5918 </p>
5919<a name="callbacks_asio"></a><h6>
5920<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.h6"></a>
5921 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.then_there_s__ulink_url__http___www_boost_org_doc_libs_release_libs_asio_index_html__boost_asio__ulink_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.then_there_s__ulink_url__http___www_boost_org_doc_libs_release_libs_asio_index_html__boost_asio__ulink_">Then
5922 There's <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a></a>
5923 </h6>
5924<p>
5925 Since the simplest form of Boost.Asio asynchronous operation completion
5926 token is a callback function, we could apply the same tactics for Asio
5927 as for our hypothetical <code class="computeroutput"><span class="identifier">AsyncAPI</span></code>
5928 asynchronous operations.
5929 </p>
5930<p>
5931 Fortunately we need not. Boost.Asio incorporates a mechanism<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f0" class="footnote">5</a>]</sup> by which the caller can customize the notification behavior
5932 of every async operation. Therefore we can construct a <span class="emphasis"><em>completion
5933 token</em></span> which, when passed to a <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a>
5934 async operation, requests blocking for the calling fiber.
5935 </p>
5936<p>
5937 A typical Asio async function might look something like this:<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f1" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f1" class="footnote">6</a>]</sup>
5938 </p>
5939<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span> <span class="special">...,</span> <span class="keyword">class</span> <span class="identifier">CompletionToken</span> <span class="special">&gt;</span>
5940<span class="emphasis"><em>deduced_return_type</em></span>
5941<span class="identifier">async_something</span><span class="special">(</span> <span class="special">...</span> <span class="special">,</span> <span class="identifier">CompletionToken</span><span class="special">&amp;&amp;</span> <span class="identifier">token</span><span class="special">)</span>
5942<span class="special">{</span>
5943 <span class="comment">// construct handler_type instance from CompletionToken</span>
5944 <span class="identifier">handler_type</span><span class="special">&lt;</span><span class="identifier">CompletionToken</span><span class="special">,</span> <span class="special">...&gt;::</span><span class="identifier">type</span> <span class="identifier">handler</span><span class="special">(</span><span class="identifier">token</span><span class="special">);</span>
5945 <span class="comment">// construct async_result instance from handler_type</span>
5946 <span class="identifier">async_result</span><span class="special">&lt;</span><span class="keyword">decltype</span><span class="special">(</span><span class="identifier">handler</span><span class="special">)&gt;</span> <span class="identifier">result</span><span class="special">(</span><span class="identifier">handler</span><span class="special">);</span>
5947
5948 <span class="comment">// ... arrange to call handler on completion ...</span>
5949 <span class="comment">// ... initiate actual I/O operation ...</span>
5950
5951 <span class="keyword">return</span> <span class="identifier">result</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
5952<span class="special">}</span>
5953</pre>
5954<p>
5955 We will engage that mechanism, which is based on specializing Asio's
5956 <code class="computeroutput"><span class="identifier">handler_type</span><span class="special">&lt;&gt;</span></code>
5957 template for the <code class="computeroutput"><span class="identifier">CompletionToken</span></code>
5958 type and the signature of the specific callback. The remainder of this
5959 discussion will refer back to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> as the Asio async function under consideration.
5960 </p>
5961<p>
5962 The implementation described below uses lower-level facilities than
5963 <code class="computeroutput"><span class="identifier">promise</span></code> and <code class="computeroutput"><span class="identifier">future</span></code> for two reasons:
5964 </p>
5965<div class="orderedlist"><ol class="orderedlist" type="1">
5966<li class="listitem">
5967 The <code class="computeroutput"><span class="identifier">promise</span></code> mechanism
5968 interacts badly with <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service/stop.html" target="_top"><code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">stop</span><span class="special">()</span></code></a>.
5969 It produces <code class="computeroutput"><span class="identifier">broken_promise</span></code>
5970 exceptions.
5971 </li>
5972<li class="listitem">
5973 If more than one thread is calling the <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service/run.html" target="_top"><code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code></a>
5974 method, the implementation described below allows resuming the suspended
5975 fiber on whichever thread gets there first with completion notification.
5976 More on this later.
5977 </li>
5978</ol></div>
5979<p>
5980 <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield</span></code> is a completion token of this
5981 kind. <code class="computeroutput"><span class="identifier">yield</span></code> is an instance
5982 of <code class="computeroutput"><span class="identifier">yield_t</span></code>:
5983 </p>
5984<p>
5985</p>
5986<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">yield_t</span> <span class="special">{</span>
5987<span class="keyword">public</span><span class="special">:</span>
5988 <span class="identifier">yield_t</span><span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">hop</span><span class="special">)</span> <span class="special">:</span>
5989 <span class="identifier">allow_hop_</span><span class="special">(</span> <span class="identifier">hop</span><span class="special">)</span> <span class="special">{</span>
5990 <span class="special">}</span>
5991
5992 <span class="comment">/**
5993 * @code
5994 * static yield_t yield;
5995 * boost::system::error_code myec;
5996 * func(yield[myec]);
5997 * @endcode
5998 * @c yield[myec] returns an instance of @c yield_t whose @c ec_ points
5999 * to @c myec. The expression @c yield[myec] "binds" @c myec to that
6000 * (anonymous) @c yield_t instance, instructing @c func() to store any
6001 * @c error_code it might produce into @c myec rather than throwing @c
6002 * boost::system::system_error.
6003 */</span>
6004 <span class="identifier">yield_t</span> <span class="keyword">operator</span><span class="special">[](</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">{</span>
6005 <span class="identifier">yield_t</span> <span class="identifier">tmp</span><span class="special">{</span> <span class="special">*</span> <span class="keyword">this</span> <span class="special">};</span>
6006 <span class="identifier">tmp</span><span class="special">.</span><span class="identifier">ec_</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">;</span>
6007 <span class="keyword">return</span> <span class="identifier">tmp</span><span class="special">;</span>
6008 <span class="special">}</span>
6009
6010<span class="comment">//private:</span>
6011 <span class="comment">// ptr to bound error_code instance if any</span>
6012 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="special">*</span> <span class="identifier">ec_</span><span class="special">{</span> <span class="keyword">nullptr</span> <span class="special">};</span>
6013 <span class="comment">// allow calling fiber to "hop" to another thread if it could resume more</span>
6014 <span class="comment">// quickly that way</span>
6015 <span class="keyword">bool</span> <span class="identifier">allow_hop_</span><span class="special">;</span>
6016<span class="special">};</span>
6017</pre>
6018<p>
6019 </p>
6020<p>
6021 <code class="computeroutput"><span class="identifier">yield_t</span></code> is in fact only
6022 a placeholder, a way to trigger Boost.Asio customization. It can bind
6023 a <a href="http://www.boost.org/doc/libs/release/libs/system/doc/reference.html#Class-error_code" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span></code></a> for use by the actual
6024 handler.
6025 </p>
6026<p>
6027 In fact there are two canonical instances of <code class="computeroutput"><span class="identifier">yield_t</span></code>
6028 &#8212; <code class="computeroutput"><span class="identifier">yield</span></code> and <code class="computeroutput"><span class="identifier">yield_hop</span></code>:
6029 </p>
6030<p>
6031</p>
6032<pre class="programlisting"><span class="comment">// canonical instance with allow_hop_ == false</span>
6033<span class="keyword">thread_local</span> <span class="identifier">yield_t</span> <span class="identifier">yield</span><span class="special">{</span> <span class="keyword">false</span> <span class="special">};</span>
6034<span class="comment">// canonical instance with allow_hop_ == true</span>
6035<span class="keyword">thread_local</span> <span class="identifier">yield_t</span> <span class="identifier">yield_hop</span><span class="special">{</span> <span class="keyword">true</span> <span class="special">};</span>
6036</pre>
6037<p>
6038 </p>
6039<p>
6040 We'll get to the differences between these shortly.
6041 </p>
6042<p>
6043 Asio customization is engaged by specializing <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/handler_type.html" target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">handler_type</span><span class="special">&lt;&gt;</span></code></a>
6044 for <code class="computeroutput"><span class="identifier">yield_t</span></code>:
6045 </p>
6046<p>
6047</p>
6048<pre class="programlisting"><span class="comment">// Handler type specialisation for fibers::asio::yield.</span>
6049<span class="comment">// When 'yield' is passed as a completion handler which accepts only</span>
6050<span class="comment">// error_code, use yield_handler&lt;void&gt;. yield_handler will take care of the</span>
6051<span class="comment">// error_code one way or another.</span>
6052<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">ReturnType</span> <span class="special">&gt;</span>
6053<span class="keyword">struct</span> <span class="identifier">handler_type</span><span class="special">&lt;</span> <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">yield_t</span><span class="special">,</span> <span class="identifier">ReturnType</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">)</span> <span class="special">&gt;</span>
6054<span class="special">{</span> <span class="keyword">typedef</span> <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;</span> <span class="identifier">type</span><span class="special">;</span> <span class="special">};</span>
6055</pre>
6056<p>
6057 </p>
6058<p>
6059 (There are actually four different specializations in <a href="../../../../../examples/asio/detail/yield.hpp" target="_top">detail/yield.hpp</a>,
6060 one for each of the four Asio async callback signatures we expect to
6061 have to support.)
6062 </p>
6063<p>
6064 The above directs Asio to use <code class="computeroutput"><span class="identifier">yield_handler</span></code>
6065 as the actual handler for an async operation to which <code class="computeroutput"><span class="identifier">yield</span></code>
6066 is passed. There's a generic <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> implementation and a <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
6067 specialization. Let's start with the <code class="computeroutput"><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
6068 specialization:
6069 </p>
6070<p>
6071</p>
6072<pre class="programlisting"><span class="comment">// yield_handler&lt;void&gt; is like yield_handler&lt;T&gt; without value_. In fact it's</span>
6073<span class="comment">// just like yield_handler_base.</span>
6074<span class="keyword">template</span><span class="special">&lt;&gt;</span>
6075<span class="keyword">class</span> <span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;:</span> <span class="keyword">public</span> <span class="identifier">yield_handler_base</span> <span class="special">{</span>
6076<span class="keyword">public</span><span class="special">:</span>
6077 <span class="keyword">explicit</span> <span class="identifier">yield_handler</span><span class="special">(</span> <span class="identifier">yield_t</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">:</span>
6078 <span class="identifier">yield_handler_base</span><span class="special">{</span> <span class="identifier">y</span> <span class="special">}</span> <span class="special">{</span>
6079 <span class="special">}</span>
6080
6081 <span class="comment">// nullary completion callback</span>
6082 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()()</span> <span class="special">{</span>
6083 <span class="special">(</span> <span class="special">*</span> <span class="keyword">this</span><span class="special">)(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">()</span> <span class="special">);</span>
6084 <span class="special">}</span>
6085
6086 <span class="comment">// inherit operator()(error_code) overload from base class</span>
6087 <span class="keyword">using</span> <span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">();</span>
6088<span class="special">};</span>
6089</pre>
6090<p>
6091 </p>
6092<p>
6093 <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>,
6094 having consulted the <code class="computeroutput"><span class="identifier">handler_type</span><span class="special">&lt;&gt;</span></code> traits specialization, instantiates
6095 a <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
6096 to be passed as the actual callback for the async operation. <code class="computeroutput"><span class="identifier">yield_handler</span></code>'s constructor accepts
6097 the <code class="computeroutput"><span class="identifier">yield_t</span></code> instance
6098 (the <code class="computeroutput"><span class="identifier">yield</span></code> object passed
6099 to the async function) and passes it along to <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>:
6100 </p>
6101<p>
6102</p>
6103<pre class="programlisting"><span class="comment">// This class encapsulates common elements between yield_handler&lt;T&gt; (capturing</span>
6104<span class="comment">// a value to return from asio async function) and yield_handler&lt;void&gt; (no</span>
6105<span class="comment">// such value). See yield_handler&lt;T&gt; and its &lt;void&gt; specialization below. Both</span>
6106<span class="comment">// yield_handler&lt;T&gt; and yield_handler&lt;void&gt; are passed by value through</span>
6107<span class="comment">// various layers of asio functions. In other words, they're potentially</span>
6108<span class="comment">// copied multiple times. So key data such as the yield_completion instance</span>
6109<span class="comment">// must be stored in our async_result&lt;yield_handler&lt;&gt;&gt; specialization, which</span>
6110<span class="comment">// should be instantiated only once.</span>
6111<span class="keyword">class</span> <span class="identifier">yield_handler_base</span> <span class="special">{</span>
6112<span class="keyword">public</span><span class="special">:</span>
6113 <span class="identifier">yield_handler_base</span><span class="special">(</span> <span class="identifier">yield_t</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">:</span>
6114 <span class="comment">// capture the context* associated with the running fiber</span>
6115 <span class="identifier">ctx_</span><span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">active</span><span class="special">()</span> <span class="special">},</span>
6116 <span class="comment">// capture the passed yield_t</span>
6117 <span class="identifier">yt_</span><span class="special">{</span> <span class="identifier">y</span> <span class="special">}</span> <span class="special">{</span>
6118 <span class="special">}</span>
6119
6120 <span class="comment">// completion callback passing only (error_code)</span>
6121 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
6122 <span class="identifier">BOOST_ASSERT_MSG</span><span class="special">(</span> <span class="identifier">ycomp_</span><span class="special">,</span>
6123 <span class="string">"Must inject yield_completion* "</span>
6124 <span class="string">"before calling yield_handler_base::operator()()"</span><span class="special">);</span>
6125 <span class="identifier">BOOST_ASSERT_MSG</span><span class="special">(</span> <span class="identifier">yt_</span><span class="special">.</span><span class="identifier">ec_</span><span class="special">,</span>
6126 <span class="string">"Must inject boost::system::error_code* "</span>
6127 <span class="string">"before calling yield_handler_base::operator()()"</span><span class="special">);</span>
6128 <span class="comment">// If originating fiber is busy testing completed_ flag, wait until it</span>
6129 <span class="comment">// has observed (! completed_).</span>
6130 <span class="identifier">yield_completion</span><span class="special">::</span><span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">{</span> <span class="identifier">ycomp_</span><span class="special">-&gt;</span><span class="identifier">mtx_</span> <span class="special">};</span>
6131 <span class="comment">// Notify a subsequent yield_completion::wait() call that it need not</span>
6132 <span class="comment">// suspend.</span>
6133 <span class="identifier">ycomp_</span><span class="special">-&gt;</span><span class="identifier">completed_</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
6134 <span class="comment">// set the error_code bound by yield_t</span>
6135 <span class="special">*</span> <span class="identifier">yt_</span><span class="special">.</span><span class="identifier">ec_</span> <span class="special">=</span> <span class="identifier">ec</span><span class="special">;</span>
6136 <span class="comment">// Are we permitted to wake up the suspended fiber on this thread, the</span>
6137 <span class="comment">// thread that called the completion handler?</span>
6138 <span class="keyword">if</span> <span class="special">(</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">ctx_</span><span class="special">-&gt;</span><span class="identifier">is_context</span><span class="special">(</span> <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">type</span><span class="special">::</span><span class="identifier">pinned_context</span><span class="special">)</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="identifier">yt_</span><span class="special">.</span><span class="identifier">allow_hop_</span><span class="special">)</span> <span class="special">{</span>
6139 <span class="comment">// We must not migrate a pinned_context to another thread. If this</span>
6140 <span class="comment">// isn't a pinned_context, and the application passed yield_hop</span>
6141 <span class="comment">// rather than yield, migrate this fiber to the running thread.</span>
6142 <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">active</span><span class="special">()-&gt;</span><span class="identifier">migrate</span><span class="special">(</span> <span class="identifier">ctx_</span><span class="special">);</span>
6143 <span class="special">}</span>
6144 <span class="comment">// either way, wake the fiber</span>
6145 <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">active</span><span class="special">()-&gt;</span><span class="identifier">set_ready</span><span class="special">(</span> <span class="identifier">ctx_</span><span class="special">);</span>
6146 <span class="special">}</span>
6147
6148<span class="comment">//private:</span>
6149 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx_</span><span class="special">;</span>
6150 <span class="identifier">yield_t</span> <span class="identifier">yt_</span><span class="special">;</span>
6151 <span class="comment">// We depend on this pointer to yield_completion, which will be injected</span>
6152 <span class="comment">// by async_result.</span>
6153 <span class="identifier">yield_completion</span> <span class="special">*</span> <span class="identifier">ycomp_</span><span class="special">{</span> <span class="keyword">nullptr</span> <span class="special">};</span>
6154<span class="special">};</span>
6155</pre>
6156<p>
6157 </p>
6158<p>
6159 <code class="computeroutput"><span class="identifier">yield_handler_base</span></code> stores
6160 a copy of the <code class="computeroutput"><span class="identifier">yield_t</span></code>
6161 instance &#8212; which, as shown above, is only an <code class="computeroutput"><span class="identifier">error_code</span></code>
6162 and a <code class="computeroutput"><span class="keyword">bool</span></code>. It also captures
6163 the <a class="link" href="../../scheduling.html#class_context"> <code class="computeroutput">context</code></a>* for the currently-running fiber by calling
6164 <a class="link" href="../../scheduling.html#context_active"> <code class="computeroutput">context::active()</code></a>.
6165 </p>
6166<p>
6167 You will notice that <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>
6168 has one more data member (<code class="computeroutput"><span class="identifier">ycomp_</span></code>)
6169 that is initialized to <code class="computeroutput"><span class="keyword">nullptr</span></code>
6170 by its constructor &#8212; though its <code class="computeroutput"><span class="keyword">operator</span><span class="special">()()</span></code> method relies on <code class="computeroutput"><span class="identifier">ycomp_</span></code>
6171 being non-null. More on this in a moment.
6172 </p>
6173<p>
6174 Having constructed the <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code> instance, <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> goes on to construct an <code class="computeroutput"><span class="identifier">async_result</span></code> specialized for the <code class="computeroutput"><span class="identifier">handler_type</span><span class="special">&lt;&gt;::</span><span class="identifier">type</span></code>: in this case, <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;</span></code>. It passes the <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
6175 instance to the new <code class="computeroutput"><span class="identifier">async_result</span></code>
6176 instance.
6177 </p>
6178<p>
6179</p>
6180<pre class="programlisting"><span class="comment">// Without the need to handle a passed value, our yield_handler&lt;void&gt;</span>
6181<span class="comment">// specialization is just like async_result_base.</span>
6182<span class="keyword">template</span><span class="special">&lt;&gt;</span>
6183<span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">:</span>
6184 <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">async_result_base</span> <span class="special">{</span>
6185<span class="keyword">public</span><span class="special">:</span>
6186 <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">type</span><span class="special">;</span>
6187
6188 <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="keyword">void</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">h</span><span class="special">):</span>
6189 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">async_result_base</span><span class="special">{</span> <span class="identifier">h</span> <span class="special">}</span> <span class="special">{</span>
6190 <span class="special">}</span>
6191<span class="special">};</span>
6192</pre>
6193<p>
6194 </p>
6195<p>
6196 Naturally that leads us straight to <code class="computeroutput"><span class="identifier">async_result_base</span></code>:
6197 </p>
6198<p>
6199</p>
6200<pre class="programlisting"><span class="comment">// Factor out commonality between async_result&lt;yield_handler&lt;T&gt;&gt; and</span>
6201<span class="comment">// async_result&lt;yield_handler&lt;void&gt;&gt;</span>
6202<span class="keyword">class</span> <span class="identifier">async_result_base</span> <span class="special">{</span>
6203<span class="keyword">public</span><span class="special">:</span>
6204 <span class="keyword">explicit</span> <span class="identifier">async_result_base</span><span class="special">(</span> <span class="identifier">yield_handler_base</span> <span class="special">&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">{</span>
6205 <span class="comment">// Inject ptr to our yield_completion instance into this</span>
6206 <span class="comment">// yield_handler&lt;&gt;.</span>
6207 <span class="identifier">h</span><span class="special">.</span><span class="identifier">ycomp_</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">ycomp_</span><span class="special">;</span>
6208 <span class="comment">// if yield_t didn't bind an error_code, make yield_handler_base's</span>
6209 <span class="comment">// error_code* point to an error_code local to this object so</span>
6210 <span class="comment">// yield_handler_base::operator() can unconditionally store through</span>
6211 <span class="comment">// its error_code*</span>
6212 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">h</span><span class="special">.</span><span class="identifier">yt_</span><span class="special">.</span><span class="identifier">ec_</span><span class="special">)</span> <span class="special">{</span>
6213 <span class="identifier">h</span><span class="special">.</span><span class="identifier">yt_</span><span class="special">.</span><span class="identifier">ec_</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">ec_</span><span class="special">;</span>
6214 <span class="special">}</span>
6215 <span class="special">}</span>
6216
6217 <span class="keyword">void</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">{</span>
6218 <span class="comment">// Unless yield_handler_base::operator() has already been called,</span>
6219 <span class="comment">// suspend the calling fiber until that call.</span>
6220 <span class="identifier">ycomp_</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span>
6221 <span class="comment">// The only way our own ec_ member could have a non-default value is</span>
6222 <span class="comment">// if our yield_handler did not have a bound error_code AND the</span>
6223 <span class="comment">// completion callback passed a non-default error_code.</span>
6224 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">ec_</span><span class="special">)</span> <span class="special">{</span>
6225 <span class="identifier">throw_exception</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">system_error</span><span class="special">{</span> <span class="identifier">ec_</span> <span class="special">}</span> <span class="special">);</span>
6226 <span class="special">}</span>
6227 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">interruption_point</span><span class="special">();</span>
6228 <span class="special">}</span>
6229
6230<span class="keyword">private</span><span class="special">:</span>
6231 <span class="comment">// If yield_t does not bind an error_code instance, store into here.</span>
6232 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec_</span><span class="special">{};</span>
6233 <span class="comment">// async_result_base owns the yield_completion because, unlike</span>
6234 <span class="comment">// yield_handler&lt;&gt;, async_result&lt;&gt; is only instantiated once.</span>
6235 <span class="identifier">yield_completion</span> <span class="identifier">ycomp_</span><span class="special">{};</span>
6236<span class="special">};</span>
6237</pre>
6238<p>
6239 </p>
6240<p>
6241 This is how <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="identifier">ycomp_</span></code>
6242 becomes non-null: <code class="computeroutput"><span class="identifier">async_result_base</span></code>'s
6243 constructor injects a pointer back to its own <code class="computeroutput"><span class="identifier">yield_completion</span></code>
6244 member.
6245 </p>
6246<p>
6247 Recall that both of the canonical <code class="computeroutput"><span class="identifier">yield_t</span></code>
6248 instances <code class="computeroutput"><span class="identifier">yield</span></code> and
6249 <code class="computeroutput"><span class="identifier">yield_hop</span></code> initialize
6250 their <code class="computeroutput"><span class="identifier">error_code</span><span class="special">*</span></code>
6251 member <code class="computeroutput"><span class="identifier">ec_</span></code> to <code class="computeroutput"><span class="keyword">nullptr</span></code>. If either of these instances
6252 is passed to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> (<code class="computeroutput"><span class="identifier">ec_</span></code>
6253 is still <code class="computeroutput"><span class="keyword">nullptr</span></code>), the copy
6254 stored in <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>
6255 will likewise have null <code class="computeroutput"><span class="identifier">ec_</span></code>.
6256 <code class="computeroutput"><span class="identifier">async_result_base</span></code>'s constructor
6257 sets <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>'s
6258 <code class="computeroutput"><span class="identifier">yield_t</span></code>'s <code class="computeroutput"><span class="identifier">ec_</span></code> member to point to its own <code class="computeroutput"><span class="identifier">error_code</span></code> member.
6259 </p>
6260<p>
6261 The stage is now set. <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> initiates the actual async operation,
6262 arranging to call its <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code> instance on completion. Let's say,
6263 for the sake of argument, that the actual async operation's callback
6264 has signature <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">)</span></code>.
6265 </p>
6266<p>
6267 But since it's an async operation, control returns at once to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>.
6268 <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>
6269 calls <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;::</span><span class="identifier">get</span><span class="special">()</span></code>,
6270 and will return its return value.
6271 </p>
6272<p>
6273 <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;&gt;::</span><span class="identifier">get</span><span class="special">()</span></code>
6274 inherits <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>.
6275 </p>
6276<p>
6277 <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>
6278 immediately calls <code class="computeroutput"><span class="identifier">yield_completion</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>.
6279 </p>
6280<p>
6281</p>
6282<pre class="programlisting"><span class="comment">// Bundle a completion bool flag with a spinlock to protect it.</span>
6283<span class="keyword">struct</span> <span class="identifier">yield_completion</span> <span class="special">{</span>
6284 <span class="keyword">typedef</span> <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">spinlock</span> <span class="identifier">mutex_t</span><span class="special">;</span>
6285 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">mutex_t</span> <span class="special">&gt;</span> <span class="identifier">lock_t</span><span class="special">;</span>
6286
6287 <span class="identifier">mutex_t</span> <span class="identifier">mtx_</span><span class="special">{};</span>
6288 <span class="keyword">bool</span> <span class="identifier">completed_</span><span class="special">{</span> <span class="keyword">false</span> <span class="special">};</span>
6289
6290 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">()</span> <span class="special">{</span>
6291 <span class="comment">// yield_handler_base::operator()() will set completed_ true and</span>
6292 <span class="comment">// attempt to wake a suspended fiber. It would be Bad if that call</span>
6293 <span class="comment">// happened between our detecting (! completed_) and suspending.</span>
6294 <span class="identifier">lock_t</span> <span class="identifier">lk</span><span class="special">{</span> <span class="identifier">mtx_</span> <span class="special">};</span>
6295 <span class="comment">// If completed_ is already set, we're done here: don't suspend.</span>
6296 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">completed_</span><span class="special">)</span> <span class="special">{</span>
6297 <span class="comment">// suspend(unique_lock&lt;spinlock&gt;) unlocks the lock in the act of</span>
6298 <span class="comment">// resuming another fiber</span>
6299 <span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span><span class="special">::</span><span class="identifier">active</span><span class="special">()-&gt;</span><span class="identifier">suspend</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">);</span>
6300 <span class="special">}</span>
6301 <span class="special">}</span>
6302<span class="special">};</span>
6303</pre>
6304<p>
6305 </p>
6306<p>
6307 Supposing that the pending async operation has not yet completed, <code class="computeroutput"><span class="identifier">yield_completion</span><span class="special">::</span><span class="identifier">completed_</span></code> will still be <code class="computeroutput"><span class="keyword">false</span></code>, and <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code> will call <a class="link" href="../../scheduling.html#context_suspend"> <code class="computeroutput">context::suspend()</code></a> on
6308 the currently-running fiber.
6309 </p>
6310<p>
6311 Other fibers will now have a chance to run.
6312 </p>
6313<p>
6314 Some time later, the async operation completes. It calls <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">error_code</span> <span class="keyword">const</span><span class="special">&amp;)</span></code> with an <code class="computeroutput"><span class="identifier">error_code</span></code>
6315 indicating either success or failure. We'll consider both cases.
6316 </p>
6317<p>
6318 <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;</span></code>
6319 explicitly inherits <code class="computeroutput"><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">error_code</span>
6320 <span class="keyword">const</span><span class="special">&amp;)</span></code>
6321 from <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>.
6322 </p>
6323<p>
6324 <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">error_code</span> <span class="keyword">const</span><span class="special">&amp;)</span></code> first sets <code class="computeroutput"><span class="identifier">yield_completion</span><span class="special">::</span><span class="identifier">completed_</span></code>
6325 <code class="computeroutput"><span class="keyword">true</span></code>. This way, if <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>'s
6326 async operation completes immediately &#8212; if <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> is called even before <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>
6327 &#8212; the calling fiber will <span class="emphasis"><em>not</em></span> suspend.
6328 </p>
6329<p>
6330 The actual <code class="computeroutput"><span class="identifier">error_code</span></code>
6331 produced by the async operation is then stored through the stored <code class="computeroutput"><span class="identifier">yield_t</span><span class="special">::</span><span class="identifier">ec_</span></code> pointer. If <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>'s caller used (e.g.) <code class="computeroutput"><span class="identifier">yield</span><span class="special">[</span><span class="identifier">my_ec</span><span class="special">]</span></code>
6332 to bind a local <code class="computeroutput"><span class="identifier">error_code</span></code>
6333 instance, the actual <code class="computeroutput"><span class="identifier">error_code</span></code>
6334 value is stored into the caller's variable. Otherwise, it is stored into
6335 <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">ec_</span></code>.
6336 </p>
6337<p>
6338 Finally we get to the distinction between <code class="computeroutput"><span class="identifier">yield</span></code>
6339 and <code class="computeroutput"><span class="identifier">yield_hop</span></code>.
6340 </p>
6341<p>
6342 As described for <a class="link" href="../../scheduling.html#context_is_context"> <code class="computeroutput">context::is_context()</code></a>, a <code class="computeroutput"><span class="identifier">pinned_context</span></code> fiber is special to
6343 the library and must never be passed to <a class="link" href="../../scheduling.html#context_migrate"> <code class="computeroutput">context::migrate()</code></a>.
6344 We must detect and avoid that case here.
6345 </p>
6346<p>
6347 The <code class="computeroutput"><span class="identifier">yield_t</span><span class="special">::</span><span class="identifier">allow_hop_</span></code> <code class="computeroutput"><span class="keyword">bool</span></code>
6348 indicates whether <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>'s caller is willing to allow the running
6349 fiber to <span class="quote">&#8220;<span class="quote">hop</span>&#8221;</span> to another thread (<code class="computeroutput"><span class="identifier">yield_hop</span></code>)
6350 or whether s/he insists that the fiber resume on the same thread (<code class="computeroutput"><span class="identifier">yield</span></code>).
6351 </p>
6352<p>
6353 If the caller passed <code class="computeroutput"><span class="identifier">yield_hop</span></code>
6354 to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>,
6355 and the running fiber isn't a <code class="computeroutput"><span class="identifier">pinned_context</span></code>,
6356 <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>
6357 passes the <code class="computeroutput"><span class="identifier">context</span></code> of
6358 the original fiber &#8212; the one on which <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> was called, captured in <code class="computeroutput"><span class="identifier">yield_handler_base</span></code>'s constructor &#8212; to
6359 the current thread's <a class="link" href="../../scheduling.html#context_migrate"> <code class="computeroutput">context::migrate()</code></a>.
6360 </p>
6361<p>
6362 If the running application has more than one thread calling <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service/run.html" target="_top"><code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code></a>,
6363 that fiber could return from <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> on a different thread (the one calling
6364 <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>)
6365 than the one on which it entered <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>.
6366 </p>
6367<p>
6368 In any case, the fiber is marked as ready to run by passing it to <a class="link" href="../../scheduling.html#context_set_ready"> <code class="computeroutput">context::set_ready()</code></a>.
6369 Control then returns from <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>: the callback is done.
6370 </p>
6371<p>
6372 In due course, the fiber <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="identifier">ctx_</span></code>
6373 is resumed. Control returns from <a class="link" href="../../scheduling.html#context_suspend"> <code class="computeroutput">context::suspend()</code></a> to
6374 <code class="computeroutput"><span class="identifier">yield_completion</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code>,
6375 which returns to <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>.
6376 </p>
6377<div class="itemizedlist"><ul class="itemizedlist" type="disc">
6378<li class="listitem">
6379 If the original caller passed <code class="computeroutput"><span class="identifier">yield</span><span class="special">[</span><span class="identifier">my_ec</span><span class="special">]</span></code> to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> to bind a local <code class="computeroutput"><span class="identifier">error_code</span></code>
6380 instance, then <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> stored its <code class="computeroutput"><span class="identifier">error_code</span></code>
6381 to the caller's <code class="computeroutput"><span class="identifier">my_ec</span></code>
6382 instance, leaving <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">ec_</span></code>
6383 initialized to success.
6384 </li>
6385<li class="listitem">
6386 If the original caller passed <code class="computeroutput"><span class="identifier">yield</span></code>
6387 to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> without binding a local <code class="computeroutput"><span class="identifier">error_code</span></code> variable, then <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code>
6388 stored its <code class="computeroutput"><span class="identifier">error_code</span></code>
6389 into <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">ec_</span></code>.
6390 If in fact that <code class="computeroutput"><span class="identifier">error_code</span></code>
6391 is success, then all is well.
6392 </li>
6393<li class="listitem">
6394 Otherwise &#8212; the original caller did not bind a local <code class="computeroutput"><span class="identifier">error_code</span></code> and <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()</span></code> was called with an <code class="computeroutput"><span class="identifier">error_code</span></code> indicating error &#8212; <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>
6395 throws <code class="computeroutput"><span class="identifier">system_error</span></code>
6396 with that <code class="computeroutput"><span class="identifier">error_code</span></code>.
6397 </li>
6398</ul></div>
6399<p>
6400 The case in which <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>'s completion callback has signature
6401 <code class="computeroutput"><span class="keyword">void</span><span class="special">()</span></code>
6402 is similar. <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">()()</span></code> invokes the machinery above with
6403 a <span class="quote">&#8220;<span class="quote">success</span>&#8221;</span> <code class="computeroutput"><span class="identifier">error_code</span></code>.
6404 </p>
6405<p>
6406 A completion callback with signature <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">T</span><span class="special">)</span></code> (that is: in addition to <code class="computeroutput"><span class="identifier">error_code</span></code>, callback receives some
6407 data item) is handled somewhat differently. For this kind of signature,
6408 <code class="computeroutput"><span class="identifier">handler_type</span><span class="special">&lt;&gt;::</span><span class="identifier">type</span></code> specifies <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> (for <code class="computeroutput"><span class="identifier">T</span></code>
6409 other than <code class="computeroutput"><span class="keyword">void</span></code>).
6410 </p>
6411<p>
6412 A <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
6413 reserves a <code class="computeroutput"><span class="identifier">value_</span></code> pointer
6414 to a value of type <code class="computeroutput"><span class="identifier">T</span></code>:
6415 </p>
6416<p>
6417</p>
6418<pre class="programlisting"><span class="comment">// asio uses handler_type&lt;completion token type, signature&gt;::type to decide</span>
6419<span class="comment">// what to instantiate as the actual handler. Below, we specialize</span>
6420<span class="comment">// handler_type&lt; yield_t, ... &gt; to indicate yield_handler&lt;&gt;. So when you pass</span>
6421<span class="comment">// an instance of yield_t as an asio completion token, asio selects</span>
6422<span class="comment">// yield_handler&lt;&gt; as the actual handler class.</span>
6423<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">&gt;</span>
6424<span class="keyword">class</span> <span class="identifier">yield_handler</span><span class="special">:</span> <span class="keyword">public</span> <span class="identifier">yield_handler_base</span> <span class="special">{</span>
6425<span class="keyword">public</span><span class="special">:</span>
6426 <span class="comment">// asio passes the completion token to the handler constructor</span>
6427 <span class="keyword">explicit</span> <span class="identifier">yield_handler</span><span class="special">(</span> <span class="identifier">yield_t</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span><span class="special">)</span> <span class="special">:</span>
6428 <span class="identifier">yield_handler_base</span><span class="special">{</span> <span class="identifier">y</span> <span class="special">}</span> <span class="special">{</span>
6429 <span class="special">}</span>
6430
6431 <span class="comment">// completion callback passing only value (T)</span>
6432 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span>
6433 <span class="comment">// just like callback passing success error_code</span>
6434 <span class="special">(*</span><span class="keyword">this</span><span class="special">)(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">(),</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span><span class="identifier">t</span><span class="special">)</span> <span class="special">);</span>
6435 <span class="special">}</span>
6436
6437 <span class="comment">// completion callback passing (error_code, T)</span>
6438 <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">,</span> <span class="identifier">T</span> <span class="identifier">t</span><span class="special">)</span> <span class="special">{</span>
6439 <span class="identifier">BOOST_ASSERT_MSG</span><span class="special">(</span> <span class="identifier">value_</span><span class="special">,</span>
6440 <span class="string">"Must inject value ptr "</span>
6441 <span class="string">"before caling yield_handler&lt;T&gt;::operator()()"</span><span class="special">);</span>
6442 <span class="comment">// move the value to async_result&lt;&gt; instance BEFORE waking up a</span>
6443 <span class="comment">// suspended fiber</span>
6444 <span class="special">*</span> <span class="identifier">value_</span> <span class="special">=</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">t</span><span class="special">);</span>
6445 <span class="comment">// forward the call to base-class completion handler</span>
6446 <span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span> <span class="identifier">ec</span><span class="special">);</span>
6447 <span class="special">}</span>
6448
6449<span class="comment">//private:</span>
6450 <span class="comment">// pointer to destination for eventual value</span>
6451 <span class="comment">// this must be injected by async_result before operator()() is called</span>
6452 <span class="identifier">T</span> <span class="special">*</span> <span class="identifier">value_</span><span class="special">{</span> <span class="keyword">nullptr</span> <span class="special">};</span>
6453<span class="special">};</span>
6454</pre>
6455<p>
6456 </p>
6457<p>
6458 This pointer is initialized to <code class="computeroutput"><span class="keyword">nullptr</span></code>.
6459 </p>
6460<p>
6461 When <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code> instantiates <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>:
6462 </p>
6463<p>
6464</p>
6465<pre class="programlisting"><span class="comment">// asio constructs an async_result&lt;&gt; instance from the yield_handler specified</span>
6466<span class="comment">// by handler_type&lt;&gt;::type. A particular asio async method constructs the</span>
6467<span class="comment">// yield_handler, constructs this async_result specialization from it, then</span>
6468<span class="comment">// returns the result of calling its get() method.</span>
6469<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">&gt;</span>
6470<span class="keyword">class</span> <span class="identifier">async_result</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">:</span>
6471 <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">async_result_base</span> <span class="special">{</span>
6472<span class="keyword">public</span><span class="special">:</span>
6473 <span class="comment">// type returned by get()</span>
6474 <span class="keyword">typedef</span> <span class="identifier">T</span> <span class="identifier">type</span><span class="special">;</span>
6475
6476 <span class="keyword">explicit</span> <span class="identifier">async_result</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">yield_handler</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">h</span><span class="special">)</span> <span class="special">:</span>
6477 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">async_result_base</span><span class="special">{</span> <span class="identifier">h</span> <span class="special">}</span> <span class="special">{</span>
6478 <span class="comment">// Inject ptr to our value_ member into yield_handler&lt;&gt;: result will</span>
6479 <span class="comment">// be stored here.</span>
6480 <span class="identifier">h</span><span class="special">.</span><span class="identifier">value_</span> <span class="special">=</span> <span class="special">&amp;</span> <span class="identifier">value_</span><span class="special">;</span>
6481 <span class="special">}</span>
6482
6483 <span class="comment">// asio async method returns result of calling get()</span>
6484 <span class="identifier">type</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">{</span>
6485 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">detail</span><span class="special">::</span><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">();</span>
6486 <span class="keyword">return</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(</span> <span class="identifier">value_</span><span class="special">);</span>
6487 <span class="special">}</span>
6488
6489<span class="keyword">private</span><span class="special">:</span>
6490 <span class="identifier">type</span> <span class="identifier">value_</span><span class="special">{};</span>
6491<span class="special">};</span>
6492</pre>
6493<p>
6494 </p>
6495<p>
6496 this <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;&gt;</span></code>
6497 specialization reserves a member of type <code class="computeroutput"><span class="identifier">T</span></code>
6498 to receive the passed data item, and sets <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">value_</span></code>
6499 to point to its own data member.
6500 </p>
6501<p>
6502 <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>
6503 overrides <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code>.
6504 The override calls <code class="computeroutput"><span class="identifier">async_result_base</span><span class="special">::</span><span class="identifier">get</span><span class="special">()</span></code>, so the calling fiber suspends as described
6505 above.
6506 </p>
6507<p>
6508 <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">error_code</span><span class="special">,</span>
6509 <span class="identifier">T</span><span class="special">)</span></code>
6510 stores its passed <code class="computeroutput"><span class="identifier">T</span></code> value
6511 into <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;::</span><span class="identifier">value_</span></code>.
6512 </p>
6513<p>
6514 Then it passes control to <code class="computeroutput"><span class="identifier">yield_handler_base</span><span class="special">::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">error_code</span><span class="special">)</span></code> to deal with waking (and possibly migrating)
6515 the original fiber as described above.
6516 </p>
6517<p>
6518 When <code class="computeroutput"><span class="identifier">async_result</span><span class="special">&lt;</span><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;::</span><span class="identifier">get</span><span class="special">()</span></code>
6519 resumes, it returns the stored <code class="computeroutput"><span class="identifier">value_</span></code>
6520 to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>
6521 and ultimately to <code class="computeroutput"><span class="identifier">async_something</span><span class="special">()</span></code>'s caller.
6522 </p>
6523<p>
6524 The case of a callback signature <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">T</span><span class="special">)</span></code> is handled by having <code class="computeroutput"><span class="identifier">yield_handler</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T</span><span class="special">)</span></code> engage the <code class="computeroutput"><span class="keyword">void</span><span class="special">(</span><span class="identifier">error_code</span><span class="special">,</span> <span class="identifier">T</span><span class="special">)</span></code> machinery, passing a <span class="quote">&#8220;<span class="quote">success</span>&#8221;</span>
6525 <code class="computeroutput"><span class="identifier">error_code</span></code>.
6526 </p>
6527<p>
6528 The source code above is found in <a href="../../../../../examples/asio/yield.hpp" target="_top">yield.hpp</a>
6529 and <a href="../../../../../examples/asio/detail/yield.hpp" target="_top">detail/yield.hpp</a>.
6530 </p>
6531</div>
6532<div class="section">
6533<div class="titlepage"><div><div><h5 class="title">
6534<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking"></a><a name="nonblocking"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking" title="Integrating Fibers with Nonblocking I/O">Integrating
6535 Fibers with Nonblocking I/O</a>
6536</h5></div></div></div>
6537<h6>
6538<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.h0"></a>
6539 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.overview">Overview</a>
6540 </h6>
6541<p>
6542 <span class="emphasis"><em>Nonblocking</em></span> I/O is distinct from <span class="emphasis"><em>asynchronous</em></span>
6543 I/O. A true async I/O operation promises to initiate the operation and
6544 notify the caller on completion, usually via some sort of callback (as
6545 described in <a class="link" href="pooled_fixedsize.html#callbacks">Integrating Fibers with Asynchronous
6546 Callbacks</a>).
6547 </p>
6548<p>
6549 In contrast, a nonblocking I/O operation refuses to start at all if it
6550 would be necessary to block, returning an error code such as <a href="http://man7.org/linux/man-pages/man3/errno.3.html" target="_top"><code class="computeroutput"><span class="identifier">EWOULDBLOCK</span></code></a>. The operation
6551 is performed only when it can complete immediately. In effect, the caller
6552 must repeatedly retry the operation until it stops returning <code class="computeroutput"><span class="identifier">EWOULDBLOCK</span></code>.
6553 </p>
6554<p>
6555 In a classic event-driven program, it can be something of a headache
6556 to use nonblocking I/O. At the point where the nonblocking I/O is attempted,
6557 a return value of <code class="computeroutput"><span class="identifier">EWOULDBLOCK</span></code>
6558 requires the caller to pass control back to the main event loop, arranging
6559 to retry again on the next iteration.
6560 </p>
6561<p>
6562 Worse, a nonblocking I/O operation might <span class="emphasis"><em>partially</em></span>
6563 succeed. That means that the relevant business logic must continue receiving
6564 control on every main loop iteration until all required data have been
6565 processed: a doubly-nested loop, implemented as a callback-driven state
6566 machine.
6567 </p>
6568<p>
6569 <span class="bold"><strong>Boost.Fiber</strong></span> can simplify this problem
6570 immensely. Once you have integrated with the application's main loop
6571 as described in <a class="link" href="pooled_fixedsize.html#integration">Sharing a Thread with Another
6572 Main Loop</a>, waiting for the next main-loop iteration is as simple
6573 as calling <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_yield"> <code class="computeroutput">this_fiber::yield()</code></a>.
6574 </p>
6575<h6>
6576<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.h1"></a>
6577 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.example_nonblocking_api"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.example_nonblocking_api">Example
6578 Nonblocking API</a>
6579 </h6>
6580<p>
6581 For purposes of illustration, consider this API:
6582 </p>
6583<p>
6584</p>
6585<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">NonblockingAPI</span> <span class="special">{</span>
6586<span class="keyword">public</span><span class="special">:</span>
6587 <span class="identifier">NonblockingAPI</span><span class="special">();</span>
6588
6589 <span class="comment">// nonblocking operation: may return EWOULDBLOCK</span>
6590 <span class="keyword">int</span> <span class="identifier">read</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">desired</span><span class="special">);</span>
6591
6592 <span class="special">...</span>
6593<span class="special">};</span>
6594</pre>
6595<p>
6596 </p>
6597<h6>
6598<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.h2"></a>
6599 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.polling_for_completion"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.polling_for_completion">Polling
6600 for Completion</a>
6601 </h6>
6602<p>
6603 We can build a low-level wrapper around <code class="computeroutput"><span class="identifier">NonblockingAPI</span><span class="special">::</span><span class="identifier">read</span><span class="special">()</span></code> that shields its caller from ever having
6604 to deal with <code class="computeroutput"><span class="identifier">EWOULDBLOCK</span></code>:
6605 </p>
6606<p>
6607</p>
6608<pre class="programlisting"><span class="comment">// guaranteed not to return EWOULDBLOCK</span>
6609<span class="keyword">int</span> <span class="identifier">read_chunk</span><span class="special">(</span> <span class="identifier">NonblockingAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">desired</span><span class="special">)</span> <span class="special">{</span>
6610 <span class="keyword">int</span> <span class="identifier">error</span><span class="special">;</span>
6611 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">EWOULDBLOCK</span> <span class="special">==</span> <span class="special">(</span> <span class="identifier">error</span> <span class="special">=</span> <span class="identifier">api</span><span class="special">.</span><span class="identifier">read</span><span class="special">(</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">desired</span><span class="special">)</span> <span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
6612 <span class="comment">// not ready yet -- try again on the next iteration of the</span>
6613 <span class="comment">// application's main loop</span>
6614 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">yield</span><span class="special">();</span>
6615 <span class="special">}</span>
6616 <span class="keyword">return</span> <span class="identifier">error</span><span class="special">;</span>
6617<span class="special">}</span>
6618</pre>
6619<p>
6620 </p>
6621<h6>
6622<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.h3"></a>
6623 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.filling_all_desired_data"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.filling_all_desired_data">Filling
6624 All Desired Data</a>
6625 </h6>
6626<p>
6627 Given <code class="computeroutput"><span class="identifier">read_chunk</span><span class="special">()</span></code>,
6628 we can straightforwardly iterate until we have all desired data:
6629 </p>
6630<p>
6631</p>
6632<pre class="programlisting"><span class="comment">// keep reading until desired length, EOF or error</span>
6633<span class="comment">// may return both partial data and nonzero error</span>
6634<span class="keyword">int</span> <span class="identifier">read_desired</span><span class="special">(</span> <span class="identifier">NonblockingAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">desired</span><span class="special">)</span> <span class="special">{</span>
6635 <span class="comment">// we're going to accumulate results into 'data'</span>
6636 <span class="identifier">data</span><span class="special">.</span><span class="identifier">clear</span><span class="special">();</span>
6637 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">chunk</span><span class="special">;</span>
6638 <span class="keyword">int</span> <span class="identifier">error</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
6639 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">length</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">desired</span> <span class="special">&amp;&amp;</span>
6640 <span class="special">(</span> <span class="identifier">error</span> <span class="special">=</span> <span class="identifier">read_chunk</span><span class="special">(</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">chunk</span><span class="special">,</span> <span class="identifier">desired</span> <span class="special">-</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">length</span><span class="special">()</span> <span class="special">)</span> <span class="special">)</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
6641 <span class="identifier">data</span><span class="special">.</span><span class="identifier">append</span><span class="special">(</span> <span class="identifier">chunk</span><span class="special">);</span>
6642 <span class="special">}</span>
6643 <span class="keyword">return</span> <span class="identifier">error</span><span class="special">;</span>
6644<span class="special">}</span>
6645</pre>
6646<p>
6647 </p>
6648<p>
6649 (Of <span class="emphasis"><em>course</em></span> there are more efficient ways to accumulate
6650 string data. That's not the point of this example.)
6651 </p>
6652<h6>
6653<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.h4"></a>
6654 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.wrapping_it_up"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.nonblocking.wrapping_it_up">Wrapping
6655 it Up</a>
6656 </h6>
6657<p>
6658 Finally, we can define a relevant exception:
6659 </p>
6660<p>
6661</p>
6662<pre class="programlisting"><span class="comment">// exception class augmented with both partially-read data and errorcode</span>
6663<span class="keyword">class</span> <span class="identifier">IncompleteRead</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="special">{</span>
6664<span class="keyword">public</span><span class="special">:</span>
6665 <span class="identifier">IncompleteRead</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">what</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">partial</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">:</span>
6666 <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span> <span class="identifier">what</span><span class="special">),</span>
6667 <span class="identifier">partial_</span><span class="special">(</span> <span class="identifier">partial</span><span class="special">),</span>
6668 <span class="identifier">ec_</span><span class="special">(</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
6669 <span class="special">}</span>
6670
6671 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">get_partial</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
6672 <span class="keyword">return</span> <span class="identifier">partial_</span><span class="special">;</span>
6673 <span class="special">}</span>
6674
6675 <span class="keyword">int</span> <span class="identifier">get_errorcode</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
6676 <span class="keyword">return</span> <span class="identifier">ec_</span><span class="special">;</span>
6677 <span class="special">}</span>
6678
6679<span class="keyword">private</span><span class="special">:</span>
6680 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">partial_</span><span class="special">;</span>
6681 <span class="keyword">int</span> <span class="identifier">ec_</span><span class="special">;</span>
6682<span class="special">};</span>
6683</pre>
6684<p>
6685 </p>
6686<p>
6687 and write a simple <code class="computeroutput"><span class="identifier">read</span><span class="special">()</span></code> function that either returns all desired
6688 data or throws <code class="computeroutput"><span class="identifier">IncompleteRead</span></code>:
6689 </p>
6690<p>
6691</p>
6692<pre class="programlisting"><span class="comment">// read all desired data or throw IncompleteRead</span>
6693<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">read</span><span class="special">(</span> <span class="identifier">NonblockingAPI</span> <span class="special">&amp;</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">desired</span><span class="special">)</span> <span class="special">{</span>
6694 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">data</span><span class="special">;</span>
6695 <span class="keyword">int</span> <span class="identifier">ec</span><span class="special">(</span> <span class="identifier">read_desired</span><span class="special">(</span> <span class="identifier">api</span><span class="special">,</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">desired</span><span class="special">)</span> <span class="special">);</span>
6696
6697 <span class="comment">// for present purposes, EOF isn't a failure</span>
6698 <span class="keyword">if</span> <span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">ec</span> <span class="special">||</span> <span class="identifier">EOF</span> <span class="special">==</span> <span class="identifier">ec</span><span class="special">)</span> <span class="special">{</span>
6699 <span class="keyword">return</span> <span class="identifier">data</span><span class="special">;</span>
6700 <span class="special">}</span>
6701
6702 <span class="comment">// oh oh, partial read</span>
6703 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">msg</span><span class="special">;</span>
6704 <span class="identifier">msg</span> <span class="special">&lt;&lt;</span> <span class="string">"NonblockingAPI::read() error "</span> <span class="special">&lt;&lt;</span> <span class="identifier">ec</span> <span class="special">&lt;&lt;</span> <span class="string">" after "</span>
6705 <span class="special">&lt;&lt;</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">length</span><span class="special">()</span> <span class="special">&lt;&lt;</span> <span class="string">" of "</span> <span class="special">&lt;&lt;</span> <span class="identifier">desired</span> <span class="special">&lt;&lt;</span> <span class="string">" characters"</span><span class="special">;</span>
6706 <span class="keyword">throw</span> <span class="identifier">IncompleteRead</span><span class="special">(</span> <span class="identifier">msg</span><span class="special">.</span><span class="identifier">str</span><span class="special">(),</span> <span class="identifier">data</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
6707<span class="special">}</span>
6708</pre>
6709<p>
6710 </p>
6711<p>
6712 Once we can transparently wait for the next main-loop iteration using
6713 <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_yield"> <code class="computeroutput">this_fiber::yield()</code></a>, ordinary encapsulation Just Works.
6714 </p>
6715<p>
6716 The source code above is found in <a href="../../../../../examples/adapt_nonblocking.cpp" target="_top">adapt_nonblocking.cpp</a>.
6717 </p>
6718</div>
6719<div class="section">
6720<div class="titlepage"><div><div><h5 class="title">
6721<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any"></a><a name="when_any"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any" title="when_any / when_all functionality">when_any
6722 / when_all functionality</a>
6723</h5></div></div></div>
6724<div class="toc"><dl>
6725<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any">when_any</a></span></dt>
6726<dd><dl>
6727<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__simple_completion">when_any,
6728 simple completion</a></span></dt>
6729<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__return_value">when_any,
6730 return value</a></span></dt>
6731<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_outcome__whether_result_or_exception">when_any,
6732 produce first outcome, whether result or exception</a></span></dt>
6733<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_success">when_any,
6734 produce first success</a></span></dt>
6735<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__heterogeneous_types">when_any,
6736 heterogeneous types</a></span></dt>
6737<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__a_dubious_alternative">when_any,
6738 a dubious alternative</a></span></dt>
6739</dl></dd>
6740<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality">when_all
6741 functionality</a></span></dt>
6742<dd><dl>
6743<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__simple_completion">when_all,
6744 simple completion</a></span></dt>
6745<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values">when_all,
6746 return values</a></span></dt>
6747<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all_until_first_exception">when_all
6748 until first exception</a></span></dt>
6749<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.wait_all__collecting_all_exceptions">wait_all,
6750 collecting all exceptions</a></span></dt>
6751<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__heterogeneous_types">when_all,
6752 heterogeneous types</a></span></dt>
6753</dl></dd>
6754</dl></div>
6755<h6>
6756<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.h0"></a>
6757 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.overview">Overview</a>
6758 </h6>
6759<p>
6760 A bit of wisdom from the early days of computing still holds true today:
6761 prefer to model program state using the instruction pointer rather than
6762 with Boolean flags. In other words, if the program must <span class="quote">&#8220;<span class="quote">do something</span>&#8221;</span>
6763 and then do something almost the same, but with minor changes... perhaps
6764 parts of that something should be broken out as smaller separate functions,
6765 rather than introducing flags to alter the internal behavior of a monolithic
6766 function.
6767 </p>
6768<p>
6769 To that we would add: prefer to describe control flow using C++ native
6770 constructs such as function calls, <code class="computeroutput"><span class="keyword">if</span></code>,
6771 <code class="computeroutput"><span class="keyword">while</span></code>, <code class="computeroutput"><span class="keyword">for</span></code>,
6772 <code class="computeroutput"><span class="keyword">do</span></code> et al. rather than as
6773 chains of callbacks.
6774 </p>
6775<p>
6776 One of the great strengths of <span class="bold"><strong>Boost.Fiber</strong></span>
6777 is the flexibility it confers on the coder to restructure an application
6778 from chains of callbacks to straightforward C++ statement sequence, even
6779 when code in that fiber is in fact interleaved with code running in other
6780 fibers.
6781 </p>
6782<p>
6783 There has been much recent discussion about the benefits of when_any
6784 and when_all functionality. When dealing with asynchronous and possibly
6785 unreliable services, these are valuable idioms. But of course when_any
6786 and when_all are closely tied to the use of chains of callbacks.
6787 </p>
6788<p>
6789 This section presents recipes for achieving the same ends, in the context
6790 of a fiber that wants to <span class="quote">&#8220;<span class="quote">do something</span>&#8221;</span> when one or more
6791 other independent activities have completed. Accordingly, these are
6792 <code class="computeroutput"><span class="identifier">wait_something</span><span class="special">()</span></code>
6793 functions rather than <code class="computeroutput"><span class="identifier">when_something</span><span class="special">()</span></code> functions. The expectation is that
6794 the calling fiber asks to launch those independent activities, then waits
6795 for them, then sequentially proceeds with whatever processing depends
6796 on those results.
6797 </p>
6798<p>
6799 The function names shown (e.g. <a class="link" href="pooled_fixedsize.html#wait_first_simple"><code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code></a>)
6800 are for illustrative purposes only, because all these functions have
6801 been bundled into a single source file. Presumably, if (say) <a class="link" href="pooled_fixedsize.html#wait_first_success"><code class="computeroutput"><span class="identifier">wait_first_success</span><span class="special">()</span></code></a>
6802 best suits your application needs, you could introduce that variant with
6803 the name <code class="computeroutput"><span class="identifier">wait_any</span><span class="special">()</span></code>.
6804 </p>
6805<div class="note"><table border="0" summary="Note">
6806<tr>
6807<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../../doc/src/images/note.png"></td>
6808<th align="left">Note</th>
6809</tr>
6810<tr><td align="left" valign="top"><p>
6811 The functions presented in this section accept variadic argument lists
6812 of task functions. Corresponding <code class="computeroutput"><span class="identifier">wait_something</span><span class="special">()</span></code> functions accepting a container of
6813 task functions are left as an exercise for the interested reader. Those
6814 should actually be simpler. Most of the complexity would arise from
6815 overloading the same name for both purposes.
6816 </p></td></tr>
6817</table></div>
6818<p>
6819 All the source code for this section is found in <a href="../../../../../examples/wait_stuff.cpp" target="_top">wait_stuff.cpp</a>.
6820 </p>
6821<h6>
6822<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.h1"></a>
6823 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.example_task_function"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.example_task_function">Example
6824 Task Function</a>
6825 </h6>
6826<p>
6827 <a name="wait_sleeper"></a>We found it convenient to model an asynchronous
6828 task using this function:
6829 </p>
6830<p>
6831</p>
6832<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">&gt;</span>
6833<span class="identifier">T</span> <span class="identifier">sleeper_impl</span><span class="special">(</span> <span class="identifier">T</span> <span class="identifier">item</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">ms</span><span class="special">,</span> <span class="keyword">bool</span> <span class="identifier">thrw</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">)</span> <span class="special">{</span>
6834 <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostringstream</span> <span class="identifier">descb</span><span class="special">,</span> <span class="identifier">funcb</span><span class="special">;</span>
6835 <span class="identifier">descb</span> <span class="special">&lt;&lt;</span> <span class="identifier">item</span><span class="special">;</span>
6836 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">desc</span><span class="special">(</span> <span class="identifier">descb</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">);</span>
6837 <span class="identifier">funcb</span> <span class="special">&lt;&lt;</span> <span class="string">" sleeper("</span> <span class="special">&lt;&lt;</span> <span class="identifier">item</span> <span class="special">&lt;&lt;</span> <span class="string">")"</span><span class="special">;</span>
6838 <span class="identifier">Verbose</span> <span class="identifier">v</span><span class="special">(</span> <span class="identifier">funcb</span><span class="special">.</span><span class="identifier">str</span><span class="special">()</span> <span class="special">);</span>
6839
6840 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">sleep_for</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">milliseconds</span><span class="special">(</span> <span class="identifier">ms</span><span class="special">)</span> <span class="special">);</span>
6841 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">thrw</span><span class="special">)</span> <span class="special">{</span>
6842 <span class="keyword">throw</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span> <span class="identifier">desc</span><span class="special">);</span>
6843 <span class="special">}</span>
6844 <span class="keyword">return</span> <span class="identifier">item</span><span class="special">;</span>
6845<span class="special">}</span>
6846</pre>
6847<p>
6848 </p>
6849<p>
6850 with type-specific <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> <span class="quote">&#8220;<span class="quote">front ends</span>&#8221;</span> for <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>, <code class="computeroutput"><span class="keyword">double</span></code>
6851 and <code class="computeroutput"><span class="keyword">int</span></code>.
6852 </p>
6853<p>
6854 <code class="computeroutput"><span class="identifier">Verbose</span></code> simply prints
6855 a message to <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span></code> on construction and destruction.
6856 </p>
6857<p>
6858 Basically:
6859 </p>
6860<div class="orderedlist"><ol class="orderedlist" type="1">
6861<li class="listitem">
6862 <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code>
6863 prints a start message;
6864 </li>
6865<li class="listitem">
6866 sleeps for the specified number of milliseconds;
6867 </li>
6868<li class="listitem">
6869 if <code class="computeroutput"><span class="identifier">thrw</span></code> is passed
6870 as <code class="computeroutput"><span class="keyword">true</span></code>, throws a string
6871 description of the passed <code class="computeroutput"><span class="identifier">item</span></code>;
6872 </li>
6873<li class="listitem">
6874 else returns the passed <code class="computeroutput"><span class="identifier">item</span></code>.
6875 </li>
6876<li class="listitem">
6877 On the way out, <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> produces a stop message.
6878 </li>
6879</ol></div>
6880<p>
6881 This function will feature in the example calls to the various functions
6882 presented below.
6883 </p>
6884<div class="section">
6885<div class="titlepage"><div><div><h6 class="title">
6886<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any" title="when_any">when_any</a>
6887</h6></div></div></div>
6888<div class="toc"><dl>
6889<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__simple_completion">when_any,
6890 simple completion</a></span></dt>
6891<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__return_value">when_any,
6892 return value</a></span></dt>
6893<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_outcome__whether_result_or_exception">when_any,
6894 produce first outcome, whether result or exception</a></span></dt>
6895<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_success">when_any,
6896 produce first success</a></span></dt>
6897<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__heterogeneous_types">when_any,
6898 heterogeneous types</a></span></dt>
6899<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__a_dubious_alternative">when_any,
6900 a dubious alternative</a></span></dt>
6901</dl></div>
6902<div class="section">
6903<div class="titlepage"><div><div><h6 class="title">
6904<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__simple_completion"></a><a name="wait_first_simple_section"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__simple_completion" title="when_any, simple completion">when_any,
6905 simple completion</a>
6906</h6></div></div></div>
6907<p>
6908 The simplest case is when you only need to know that the first of
6909 a set of asynchronous tasks has completed &#8212; but you don't need to obtain
6910 a return value, and you're confident that they will not throw exceptions.
6911 </p>
6912<p>
6913 <a name="wait_done"></a>For this we introduce a <code class="computeroutput"><span class="identifier">Done</span></code>
6914 class to wrap a <code class="computeroutput"><span class="keyword">bool</span></code>
6915 variable with a <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> and a <a class="link" href="pooled_fixedsize.html#class_mutex"> <code class="computeroutput">mutex</code></a>:
6916 </p>
6917<p>
6918</p>
6919<pre class="programlisting"><span class="comment">// Wrap canonical pattern for condition_variable + bool flag</span>
6920<span class="keyword">struct</span> <span class="identifier">Done</span> <span class="special">{</span>
6921<span class="keyword">private</span><span class="special">:</span>
6922 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">cond</span><span class="special">;</span>
6923 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mutex</span><span class="special">;</span>
6924 <span class="keyword">bool</span> <span class="identifier">ready</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
6925
6926<span class="keyword">public</span><span class="special">:</span>
6927 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">Done</span> <span class="special">&gt;</span> <span class="identifier">ptr</span><span class="special">;</span>
6928
6929 <span class="keyword">void</span> <span class="identifier">wait</span><span class="special">()</span> <span class="special">{</span>
6930 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span> <span class="identifier">mutex</span><span class="special">);</span>
6931 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lock</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](){</span> <span class="keyword">return</span> <span class="identifier">ready</span><span class="special">;</span> <span class="special">});</span>
6932 <span class="special">}</span>
6933
6934 <span class="keyword">void</span> <span class="identifier">notify</span><span class="special">()</span> <span class="special">{</span>
6935 <span class="special">{</span>
6936 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lock</span><span class="special">(</span> <span class="identifier">mutex</span><span class="special">);</span>
6937 <span class="identifier">ready</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
6938 <span class="special">}</span> <span class="comment">// release mutex</span>
6939 <span class="identifier">cond</span><span class="special">.</span><span class="identifier">notify_one</span><span class="special">();</span>
6940 <span class="special">}</span>
6941<span class="special">};</span>
6942</pre>
6943<p>
6944 </p>
6945<p>
6946 The pattern we follow throughout this section is to pass a <a href="http://www.cplusplus.com/reference/memory/shared_ptr/" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;&gt;</span></code></a>
6947 to the relevant synchronization object to the various tasks' fiber
6948 functions. This eliminates nagging questions about the lifespan of
6949 the synchronization object relative to the last of the fibers.
6950 </p>
6951<p>
6952 <a name="wait_first_simple"></a><code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> uses that tactic for <a class="link" href="pooled_fixedsize.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a>:
6953 </p>
6954<p>
6955</p>
6956<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
6957<span class="keyword">void</span> <span class="identifier">wait_first_simple</span><span class="special">(</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
6958 <span class="comment">// Use shared_ptr because each function's fiber will bind it separately,</span>
6959 <span class="comment">// and we're going to return before the last of them completes.</span>
6960 <span class="keyword">auto</span> <span class="identifier">done</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">Done</span> <span class="special">&gt;()</span> <span class="special">);</span>
6961 <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
6962 <span class="identifier">done</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span>
6963<span class="special">}</span>
6964</pre>
6965<p>
6966 </p>
6967<p>
6968 <a name="wait_first_simple_impl"></a><code class="computeroutput"><span class="identifier">wait_first_simple_impl</span><span class="special">()</span></code> is an ordinary recursion over the
6969 argument pack, capturing <code class="computeroutput"><span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span></code>
6970 for each new fiber:
6971 </p>
6972<p>
6973</p>
6974<pre class="programlisting"><span class="comment">// Degenerate case: when there are no functions to wait for, return</span>
6975<span class="comment">// immediately.</span>
6976<span class="keyword">void</span> <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span><span class="special">)</span> <span class="special">{</span>
6977<span class="special">}</span>
6978
6979<span class="comment">// When there's at least one function to wait for, launch it and recur to</span>
6980<span class="comment">// process the rest.</span>
6981<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
6982<span class="keyword">void</span> <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">Done</span><span class="special">::</span><span class="identifier">ptr</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
6983 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span> <span class="special">[</span><span class="identifier">done</span><span class="special">,</span> <span class="identifier">function</span><span class="special">](){</span>
6984 <span class="identifier">function</span><span class="special">();</span>
6985 <span class="identifier">done</span><span class="special">-&gt;</span><span class="identifier">notify</span><span class="special">();</span>
6986 <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
6987 <span class="identifier">wait_first_simple_impl</span><span class="special">(</span> <span class="identifier">done</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
6988<span class="special">}</span>
6989</pre>
6990<p>
6991 </p>
6992<p>
6993 The body of the fiber's lambda is extremely simple, as promised:
6994 call the function, notify <a class="link" href="pooled_fixedsize.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a> when it returns. The
6995 first fiber to do so allows <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> to return &#8212; which is why it's useful
6996 to have <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">Done</span><span class="special">&gt;</span></code>
6997 manage the lifespan of our <code class="computeroutput"><span class="identifier">Done</span></code>
6998 object rather than declaring it as a stack variable in <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code>.
6999 </p>
7000<p>
7001 This is how you might call it:
7002 </p>
7003<p>
7004</p>
7005<pre class="programlisting"><span class="identifier">wait_first_simple</span><span class="special">(</span>
7006 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_long"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7007 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_medium"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7008 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_short"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7009</pre>
7010<p>
7011 </p>
7012<p>
7013 In this example, control resumes after <code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code> when <a class="link" href="pooled_fixedsize.html#wait_sleeper"><code class="computeroutput"><span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfs_short"</span><span class="special">,</span>
7014 <span class="number">50</span><span class="special">)</span></code></a>
7015 completes &#8212; even though the other two <code class="computeroutput"><span class="identifier">sleeper</span><span class="special">()</span></code> fibers are still running.
7016 </p>
7017</div>
7018<div class="section">
7019<div class="titlepage"><div><div><h6 class="title">
7020<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__return_value"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__return_value" title="when_any, return value">when_any,
7021 return value</a>
7022</h6></div></div></div>
7023<p>
7024 It seems more useful to add the ability to capture the return value
7025 from the first of the task functions to complete. Again, we assume
7026 that none will throw an exception.
7027 </p>
7028<p>
7029 One tactic would be to adapt our <a class="link" href="pooled_fixedsize.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a> class to store the
7030 first of the return values, rather than a simple <code class="computeroutput"><span class="keyword">bool</span></code>.
7031 However, we choose instead to use a <a class="link" href="pooled_fixedsize.html#class_unbounded_channel"> <code class="computeroutput">unbounded_channel&lt;&gt;</code></a>.
7032 We'll only need to enqueue the first value, so we'll <a class="link" href="pooled_fixedsize.html#unbounded_channel_close"> <code class="computeroutput">unbounded_channel::close()</code></a> it
7033 once we've retrieved that value. Subsequent <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code> calls will return <code class="computeroutput"><span class="identifier">closed</span></code>.
7034 </p>
7035<p>
7036 <a name="wait_first_value"></a>
7037</p>
7038<pre class="programlisting"><span class="comment">// Assume that all passed functions have the same return type. The return type</span>
7039<span class="comment">// of wait_first_value() is the return type of the first passed function. It is</span>
7040<span class="comment">// simply invalid to pass NO functions.</span>
7041<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7042<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span>
7043<span class="identifier">wait_first_value</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7044 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7045 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7046 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7047 <span class="comment">// launch all the relevant fibers</span>
7048 <span class="identifier">wait_first_value_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span>
7049 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7050 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7051 <span class="comment">// retrieve the first value</span>
7052 <span class="identifier">return_t</span> <span class="identifier">value</span><span class="special">(</span> <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span> <span class="special">);</span>
7053 <span class="comment">// close the channel: no subsequent push() has to succeed</span>
7054 <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7055 <span class="keyword">return</span> <span class="identifier">value</span><span class="special">;</span>
7056<span class="special">}</span>
7057</pre>
7058<p>
7059 </p>
7060<p>
7061 <a name="wait_first_value_impl"></a>The meat of the <code class="computeroutput"><span class="identifier">wait_first_value_impl</span><span class="special">()</span></code>
7062 function is as you might expect:
7063 </p>
7064<p>
7065</p>
7066<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
7067<span class="keyword">void</span> <span class="identifier">wait_first_value_impl</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span><span class="special">,</span>
7068 <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">)</span> <span class="special">{</span>
7069 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span> <span class="special">[</span><span class="identifier">channel</span><span class="special">,</span> <span class="identifier">function</span><span class="special">](){</span>
7070 <span class="comment">// Ignore channel_op_status returned by push():</span>
7071 <span class="comment">// might be closed; we simply don't care.</span>
7072 <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">function</span><span class="special">()</span> <span class="special">);</span>
7073 <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
7074<span class="special">}</span>
7075</pre>
7076<p>
7077 </p>
7078<p>
7079 It calls the passed function, pushes its return value and ignores
7080 the <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>
7081 result. You might call it like this:
7082 </p>
7083<p>
7084</p>
7085<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">wait_first_value</span><span class="special">(</span>
7086 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfv_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7087 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfv_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7088 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfv_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7089<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_first_value() =&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7090<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="string">"wfv_first"</span><span class="special">);</span>
7091</pre>
7092<p>
7093 </p>
7094</div>
7095<div class="section">
7096<div class="titlepage"><div><div><h6 class="title">
7097<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_outcome__whether_result_or_exception"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_outcome__whether_result_or_exception" title="when_any, produce first outcome, whether result or exception">when_any,
7098 produce first outcome, whether result or exception</a>
7099</h6></div></div></div>
7100<p>
7101 We may not be running in an environment in which we can guarantee
7102 no exception will be thrown by any of our task functions. In that
7103 case, the above implementations of <code class="computeroutput"><span class="identifier">wait_first_something</span><span class="special">()</span></code> would be na&#239;ve: as mentioned in
7104 <a class="link" href="../../fiber_mgmt.html#exceptions">the section on Fiber Management</a>,
7105 an uncaught exception in one of our task fibers would cause <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">terminate</span><span class="special">()</span></code>
7106 to be called.
7107 </p>
7108<p>
7109 Let's at least ensure that such an exception would propagate to the
7110 fiber awaiting the first result. We can use <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a> to
7111 transport either a return value or an exception. Therefore, we will
7112 change <a class="link" href="pooled_fixedsize.html#wait_first_value"><code class="computeroutput"><span class="identifier">wait_first_value</span><span class="special">()</span></code></a>'s <a class="link" href="pooled_fixedsize.html#class_unbounded_channel"> <code class="computeroutput">unbounded_channel&lt;&gt;</code></a> to
7113 hold <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;</span>
7114 <span class="identifier">T</span> <span class="special">&gt;</span></code>
7115 items instead of simply <code class="computeroutput"><span class="identifier">T</span></code>.
7116 </p>
7117<p>
7118 Once we have a <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> in hand, all we need do is
7119 call <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a>, which will either return the value
7120 or rethrow the exception.
7121 </p>
7122<p>
7123 <a name="wait_first_outcome"></a>
7124</p>
7125<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7126<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span>
7127<span class="identifier">wait_first_outcome</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7128 <span class="comment">// In this case, the value we pass through the channel is actually a</span>
7129 <span class="comment">// future -- which is already ready. future can carry either a value or an</span>
7130 <span class="comment">// exception.</span>
7131 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7132 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7133 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7134 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7135 <span class="comment">// launch all the relevant fibers</span>
7136 <span class="identifier">wait_first_outcome_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span>
7137 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7138 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7139 <span class="comment">// retrieve the first future</span>
7140 <span class="identifier">future_t</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span> <span class="special">);</span>
7141 <span class="comment">// close the channel: no subsequent push() has to succeed</span>
7142 <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7143 <span class="comment">// either return value or throw exception</span>
7144 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
7145<span class="special">}</span>
7146</pre>
7147<p>
7148 </p>
7149<p>
7150 So far so good &#8212; but there's a timing issue. How should we obtain the
7151 <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
7152 to <a class="link" href="pooled_fixedsize.html#unbounded_channel_push"> <code class="computeroutput">unbounded_channel::push()</code></a> on the channel?
7153 </p>
7154<p>
7155 We could call <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a>. That would certainly produce
7156 a <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
7157 for the task function. The trouble is that it would return too quickly!
7158 We only want <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> items for <span class="emphasis"><em>completed</em></span>
7159 tasks on our <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;&gt;</span></code>. In fact, we only want the
7160 <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
7161 for the one that completes first. If each fiber launched by <code class="computeroutput"><span class="identifier">wait_first_outcome</span><span class="special">()</span></code>
7162 were to <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>
7163 the result of calling <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code>, the channel would only ever report
7164 the result of the leftmost task item &#8212; <span class="emphasis"><em>not</em></span> the
7165 one that completes most quickly.
7166 </p>
7167<p>
7168 Calling <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> on the future returned by <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code>
7169 wouldn't be right. You can only call <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> once per <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> instance! And if there were
7170 an exception, it would be rethrown inside the helper fiber at the
7171 producer end of the channel, rather than propagated to the consumer
7172 end.
7173 </p>
7174<p>
7175 We could call <a class="link" href="pooled_fixedsize.html#future_wait"> <code class="computeroutput">future::wait()</code></a>. That would block the helper
7176 fiber until the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> became ready, at which point
7177 we could <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>
7178 it to be retrieved by <code class="computeroutput"><span class="identifier">wait_first_outcome</span><span class="special">()</span></code>.
7179 </p>
7180<p>
7181 That would work &#8212; but there's a simpler tactic that avoids creating
7182 an extra fiber. We can wrap the task function in a <a class="link" href="pooled_fixedsize.html#class_packaged_task"> <code class="computeroutput">packaged_task&lt;&gt;</code></a>.
7183 While one naturally thinks of passing a <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code> to a new fiber &#8212; that is, in
7184 fact, what <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code> does &#8212; in this case, we're already
7185 running in the helper fiber at the producer end of the channel! We
7186 can simply <span class="emphasis"><em>call</em></span> the <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code>. On return from that call,
7187 the task function has completed, meaning that the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> obtained from the <code class="computeroutput"><span class="identifier">packaged_task</span><span class="special">&lt;&gt;</span></code>
7188 is certain to be ready. At that point we can simply <code class="computeroutput"><span class="identifier">push</span><span class="special">()</span></code>
7189 it to the channel.
7190 </p>
7191<p>
7192 <a name="wait_first_outcome_impl"></a>
7193</p>
7194<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">CHANNELP</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
7195<span class="keyword">void</span> <span class="identifier">wait_first_outcome_impl</span><span class="special">(</span> <span class="identifier">CHANNELP</span> <span class="identifier">channel</span><span class="special">,</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">)</span> <span class="special">{</span>
7196 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span>
7197 <span class="comment">// Use std::bind() here for C++11 compatibility. C++11 lambda capture</span>
7198 <span class="comment">// can't move a move-only Fn type, but bind() can. Let bind() move the</span>
7199 <span class="comment">// channel pointer and the function into the bound object, passing</span>
7200 <span class="comment">// references into the lambda.</span>
7201 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
7202 <span class="special">[](</span> <span class="identifier">CHANNELP</span> <span class="special">&amp;</span> <span class="identifier">channel</span><span class="special">,</span>
7203 <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&amp;</span> <span class="identifier">function</span><span class="special">)</span> <span class="special">{</span>
7204 <span class="comment">// Instantiate a packaged_task to capture any exception thrown by</span>
7205 <span class="comment">// function.</span>
7206 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">packaged_task</span><span class="special">&lt;</span> <span class="identifier">T</span><span class="special">()</span> <span class="special">&gt;</span> <span class="identifier">task</span><span class="special">(</span> <span class="identifier">function</span><span class="special">);</span>
7207 <span class="comment">// Immediately run this packaged_task on same fiber. We want</span>
7208 <span class="comment">// function() to have completed BEFORE we push the future.</span>
7209 <span class="identifier">task</span><span class="special">();</span>
7210 <span class="comment">// Pass the corresponding future to consumer. Ignore</span>
7211 <span class="comment">// channel_op_status returned by push(): might be closed; we</span>
7212 <span class="comment">// simply don't care.</span>
7213 <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">task</span><span class="special">.</span><span class="identifier">get_future</span><span class="special">()</span> <span class="special">);</span>
7214 <span class="special">},</span>
7215 <span class="identifier">channel</span><span class="special">,</span>
7216 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">)</span>
7217 <span class="special">)).</span><span class="identifier">detach</span><span class="special">();</span>
7218<span class="special">}</span>
7219</pre>
7220<p>
7221 </p>
7222<p>
7223 Calling it might look like this:
7224 </p>
7225<p>
7226</p>
7227<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">wait_first_outcome</span><span class="special">(</span>
7228 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfos_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">},</span>
7229 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfos_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7230 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfos_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">});</span>
7231<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_first_outcome(success) =&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7232<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="string">"wfos_first"</span><span class="special">);</span>
7233
7234<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">thrown</span><span class="special">;</span>
7235<span class="keyword">try</span> <span class="special">{</span>
7236 <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">wait_first_outcome</span><span class="special">(</span>
7237 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfof_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span> <span class="special">},</span>
7238 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfof_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7239 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfof_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">});</span>
7240<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
7241 <span class="identifier">thrown</span> <span class="special">=</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
7242<span class="special">}</span>
7243<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_first_outcome(fail) threw '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">thrown</span>
7244 <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7245<span class="identifier">assert</span><span class="special">(</span><span class="identifier">thrown</span> <span class="special">==</span> <span class="string">"wfof_first"</span><span class="special">);</span>
7246</pre>
7247<p>
7248 </p>
7249</div>
7250<div class="section">
7251<div class="titlepage"><div><div><h6 class="title">
7252<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_success"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__produce_first_success" title="when_any, produce first success">when_any,
7253 produce first success</a>
7254</h6></div></div></div>
7255<p>
7256 One scenario for <span class="quote">&#8220;<span class="quote">when_any</span>&#8221;</span> functionality is when we're
7257 redundantly contacting some number of possibly-unreliable web services.
7258 Not only might they be slow &#8212; any one of them might produce a failure
7259 rather than the desired result.
7260 </p>
7261<p>
7262 In such a case, <a class="link" href="pooled_fixedsize.html#wait_first_outcome"><code class="computeroutput"><span class="identifier">wait_first_outcome</span><span class="special">()</span></code></a>
7263 isn't the right approach. If one of the services produces an error
7264 quickly, while another follows up with a real answer, we don't want
7265 to prefer the error just because it arrived first!
7266 </p>
7267<p>
7268 Given the <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">T</span>
7269 <span class="special">&gt;</span> <span class="special">&gt;</span></code>
7270 we already constructed for <code class="computeroutput"><span class="identifier">wait_first_outcome</span><span class="special">()</span></code>, though, we can readily recast
7271 the interface function to deliver the first <span class="emphasis"><em>successful</em></span>
7272 result.
7273 </p>
7274<p>
7275 That does beg the question: what if <span class="emphasis"><em>all</em></span> the
7276 task functions throw an exception? In that case we'd probably better
7277 know about it.
7278 </p>
7279<p>
7280 <a name="exception_list"></a>The <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4407.html#parallel.exceptions.synopsis" target="_top">C++
7281 Parallelism Draft Technical Specification</a> proposes a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_list</span></code> exception capable
7282 of delivering a collection of <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>s.
7283 Until that becomes universally available, let's fake up an <code class="computeroutput"><span class="identifier">exception_list</span></code> of our own:
7284 </p>
7285<p>
7286</p>
7287<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">exception_list</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span> <span class="special">{</span>
7288<span class="keyword">public</span><span class="special">:</span>
7289 <span class="identifier">exception_list</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">what</span><span class="special">)</span> <span class="special">:</span>
7290 <span class="identifier">std</span><span class="special">::</span><span class="identifier">runtime_error</span><span class="special">(</span> <span class="identifier">what</span><span class="special">)</span> <span class="special">{</span>
7291 <span class="special">}</span>
7292
7293 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="special">&gt;</span> <span class="identifier">bundle_t</span><span class="special">;</span>
7294
7295 <span class="comment">// N4407 proposed std::exception_list API</span>
7296 <span class="keyword">typedef</span> <span class="identifier">bundle_t</span><span class="special">::</span><span class="identifier">const_iterator</span> <span class="identifier">iterator</span><span class="special">;</span>
7297
7298 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
7299 <span class="keyword">return</span> <span class="identifier">bundle_</span><span class="special">.</span><span class="identifier">size</span><span class="special">();</span>
7300 <span class="special">}</span>
7301
7302 <span class="identifier">iterator</span> <span class="identifier">begin</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
7303 <span class="keyword">return</span> <span class="identifier">bundle_</span><span class="special">.</span><span class="identifier">begin</span><span class="special">();</span>
7304 <span class="special">}</span>
7305
7306 <span class="identifier">iterator</span> <span class="identifier">end</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
7307 <span class="keyword">return</span> <span class="identifier">bundle_</span><span class="special">.</span><span class="identifier">end</span><span class="special">();</span>
7308 <span class="special">}</span>
7309
7310 <span class="comment">// extension to populate</span>
7311 <span class="keyword">void</span> <span class="identifier">add</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">ep</span><span class="special">)</span> <span class="special">{</span>
7312 <span class="identifier">bundle_</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">ep</span><span class="special">);</span>
7313 <span class="special">}</span>
7314
7315<span class="keyword">private</span><span class="special">:</span>
7316 <span class="identifier">bundle_t</span> <span class="identifier">bundle_</span><span class="special">;</span>
7317<span class="special">};</span>
7318</pre>
7319<p>
7320 </p>
7321<p>
7322 Now we can build <code class="computeroutput"><span class="identifier">wait_first_success</span><span class="special">()</span></code>, using <a class="link" href="pooled_fixedsize.html#wait_first_outcome_impl"><code class="computeroutput"><span class="identifier">wait_first_outcome_impl</span><span class="special">()</span></code></a>.
7323 </p>
7324<p>
7325 Instead of retrieving only the first <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> from the channel, we must
7326 now loop over <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> items. Of course we must
7327 limit that iteration! If we launch only <code class="computeroutput"><span class="identifier">count</span></code>
7328 producer fibers, the <code class="computeroutput"><span class="special">(</span><span class="identifier">count</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code>
7329 <sup>st</sup>
7330 <a class="link" href="pooled_fixedsize.html#unbounded_channel_pop"> <code class="computeroutput">unbounded_channel::pop()</code></a> call would block forever.
7331 </p>
7332<p>
7333 Given a ready <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>, we can distinguish failure
7334 by calling <a class="link" href="pooled_fixedsize.html#future_get_exception_ptr"> <code class="computeroutput">future::get_exception_ptr()</code></a>. If
7335 the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>
7336 in fact contains a result rather than an exception, <code class="computeroutput"><span class="identifier">get_exception_ptr</span><span class="special">()</span></code>
7337 returns <code class="computeroutput"><span class="keyword">nullptr</span></code>. In
7338 that case, we can confidently call <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> to return
7339 that result to our caller.
7340 </p>
7341<p>
7342 If the <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code> is <span class="emphasis"><em>not</em></span>
7343 <code class="computeroutput"><span class="keyword">nullptr</span></code>, though, we
7344 collect it into our pending <code class="computeroutput"><span class="identifier">exception_list</span></code>
7345 and loop back for the next <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code> from the channel.
7346 </p>
7347<p>
7348 If we fall out of the loop &#8212; if every single task fiber threw an exception
7349 &#8212; we throw the <code class="computeroutput"><span class="identifier">exception_list</span></code>
7350 exception into which we've been collecting those <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span></code>s.
7351 </p>
7352<p>
7353 <a name="wait_first_success"></a>
7354</p>
7355<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7356<span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span>
7357<span class="identifier">wait_first_success</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7358 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7359 <span class="comment">// In this case, the value we pass through the channel is actually a</span>
7360 <span class="comment">// future -- which is already ready. future can carry either a value or an</span>
7361 <span class="comment">// exception.</span>
7362 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;::</span><span class="identifier">type</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7363 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7364 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7365 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7366 <span class="comment">// launch all the relevant fibers</span>
7367 <span class="identifier">wait_first_outcome_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span>
7368 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7369 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7370 <span class="comment">// instantiate exception_list, just in case</span>
7371 <span class="identifier">exception_list</span> <span class="identifier">exceptions</span><span class="special">(</span><span class="string">"wait_first_success() produced only errors"</span><span class="special">);</span>
7372 <span class="comment">// retrieve up to 'count' results -- but stop there!</span>
7373 <span class="keyword">for</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special">&lt;</span> <span class="identifier">count</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
7374 <span class="comment">// retrieve the next future</span>
7375 <span class="identifier">future_t</span> <span class="identifier">future</span><span class="special">(</span> <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span> <span class="special">);</span>
7376 <span class="comment">// retrieve exception_ptr if any</span>
7377 <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">error</span><span class="special">(</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get_exception_ptr</span><span class="special">()</span> <span class="special">);</span>
7378 <span class="comment">// if no error, then yay, return value</span>
7379 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">error</span><span class="special">)</span> <span class="special">{</span>
7380 <span class="comment">// close the channel: no subsequent push() has to succeed</span>
7381 <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7382 <span class="comment">// show caller the value we got</span>
7383 <span class="keyword">return</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
7384 <span class="special">}</span>
7385
7386 <span class="comment">// error is non-null: collect</span>
7387 <span class="identifier">exceptions</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span> <span class="identifier">error</span><span class="special">);</span>
7388 <span class="special">}</span>
7389 <span class="comment">// We only arrive here when every passed function threw an exception.</span>
7390 <span class="comment">// Throw our collection to inform caller.</span>
7391 <span class="keyword">throw</span> <span class="identifier">exceptions</span><span class="special">;</span>
7392<span class="special">}</span>
7393</pre>
7394<p>
7395 </p>
7396<p>
7397 A call might look like this:
7398 </p>
7399<p>
7400</p>
7401<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">wait_first_success</span><span class="special">(</span>
7402 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfss_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span> <span class="special">},</span>
7403 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfss_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7404 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfss_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">});</span>
7405<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_first_success(success) =&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7406<span class="identifier">assert</span><span class="special">(</span><span class="identifier">result</span> <span class="special">==</span> <span class="string">"wfss_second"</span><span class="special">);</span>
7407</pre>
7408<p>
7409 </p>
7410</div>
7411<div class="section">
7412<div class="titlepage"><div><div><h6 class="title">
7413<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__heterogeneous_types"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__heterogeneous_types" title="when_any, heterogeneous types">when_any,
7414 heterogeneous types</a>
7415</h6></div></div></div>
7416<p>
7417 We would be remiss to ignore the case in which the various task functions
7418 have distinct return types. That means that the value returned by
7419 the first of them might have any one of those types. We can express
7420 that with <a href="http://www.boost.org/doc/libs/release/doc/html/variant.html" target="_top">Boost.Variant</a>.
7421 </p>
7422<p>
7423 To keep the example simple, we'll revert to pretending that none
7424 of them can throw an exception. That makes <code class="computeroutput"><span class="identifier">wait_first_value_het</span><span class="special">()</span></code> strongly resemble <a class="link" href="pooled_fixedsize.html#wait_first_value"><code class="computeroutput"><span class="identifier">wait_first_value</span><span class="special">()</span></code></a>.
7425 We can actually reuse <a class="link" href="pooled_fixedsize.html#wait_first_value_impl"><code class="computeroutput"><span class="identifier">wait_first_value_impl</span><span class="special">()</span></code></a>,
7426 merely passing <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span><span class="identifier">T0</span><span class="special">,</span> <span class="identifier">T1</span><span class="special">,</span> <span class="special">...&gt;</span></code>
7427 as the channel's value type rather than the common <code class="computeroutput"><span class="identifier">T</span></code>!
7428 </p>
7429<p>
7430 Naturally this could be extended to use <a class="link" href="pooled_fixedsize.html#wait_first_success"><code class="computeroutput"><span class="identifier">wait_first_success</span><span class="special">()</span></code></a>
7431 semantics instead.
7432 </p>
7433<p>
7434</p>
7435<pre class="programlisting"><span class="comment">// No need to break out the first Fn for interface function: let the compiler</span>
7436<span class="comment">// complain if empty.</span>
7437<span class="comment">// Our functions have different return types, and we might have to return any</span>
7438<span class="comment">// of them. Use a variant, expanding std::result_of&lt;Fn()&gt;::type for each Fn in</span>
7439<span class="comment">// parameter pack.</span>
7440<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7441<span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fns</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">...</span> <span class="special">&gt;</span>
7442<span class="identifier">wait_first_value_het</span><span class="special">(</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7443 <span class="comment">// Use unbounded_channel&lt;boost::variant&lt;T1, T2, ...&gt;&gt;; see remarks above.</span>
7444 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fns</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">...</span> <span class="special">&gt;</span> <span class="identifier">return_t</span><span class="special">;</span>
7445 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7446 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7447 <span class="comment">// launch all the relevant fibers</span>
7448 <span class="identifier">wait_first_value_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span>
7449 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7450 <span class="comment">// retrieve the first value</span>
7451 <span class="identifier">return_t</span> <span class="identifier">value</span><span class="special">(</span> <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">value_pop</span><span class="special">()</span> <span class="special">);</span>
7452 <span class="comment">// close the channel: no subsequent push() has to succeed</span>
7453 <span class="identifier">channelp</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7454 <span class="keyword">return</span> <span class="identifier">value</span><span class="special">;</span>
7455<span class="special">}</span>
7456</pre>
7457<p>
7458 </p>
7459<p>
7460 It might be called like this:
7461 </p>
7462<p>
7463</p>
7464<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">,</span> <span class="keyword">double</span><span class="special">,</span> <span class="keyword">int</span> <span class="special">&gt;</span> <span class="identifier">result</span> <span class="special">=</span>
7465 <span class="identifier">wait_first_value_het</span><span class="special">(</span>
7466 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wfvh_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7467 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7468 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="number">17</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7469<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_first_value_het() =&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">result</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7470<span class="identifier">assert</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">get</span><span class="special">&lt;</span> <span class="keyword">int</span> <span class="special">&gt;(</span> <span class="identifier">result</span><span class="special">)</span> <span class="special">==</span> <span class="number">17</span><span class="special">);</span>
7471</pre>
7472<p>
7473 </p>
7474</div>
7475<div class="section">
7476<div class="titlepage"><div><div><h6 class="title">
7477<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__a_dubious_alternative"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_any.when_any__a_dubious_alternative" title="when_any, a dubious alternative">when_any,
7478 a dubious alternative</a>
7479</h6></div></div></div>
7480<p>
7481 Certain topics in C++ can arouse strong passions, and exceptions
7482 are no exception. We cannot resist mentioning &#8212; for purely informational
7483 purposes &#8212; that when you need only the <span class="emphasis"><em>first</em></span> result
7484 from some number of concurrently-running fibers, it would be possible
7485 to pass a <code class="computeroutput">shared_ptr&lt; <a class="link" href="pooled_fixedsize.html#class_promise"> <code class="computeroutput">promise&lt;&gt;</code></a>&gt;</code> to the participating
7486 fibers, then cause the initiating fiber to call <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> on
7487 its <a class="link" href="pooled_fixedsize.html#class_future"> <code class="computeroutput">future&lt;&gt;</code></a>. The first fiber to call <a class="link" href="pooled_fixedsize.html#promise_set_value"> <code class="computeroutput">promise::set_value()</code></a> on
7488 that shared <code class="computeroutput"><span class="identifier">promise</span></code>
7489 will succeed; subsequent <code class="computeroutput"><span class="identifier">set_value</span><span class="special">()</span></code> calls on the same <code class="computeroutput"><span class="identifier">promise</span></code> instance will throw <code class="computeroutput"><span class="identifier">future_error</span></code>.
7490 </p>
7491<p>
7492 Use this information at your own discretion. Beware the dark side.
7493 </p>
7494</div>
7495</div>
7496<div class="section">
7497<div class="titlepage"><div><div><h6 class="title">
7498<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality" title="when_all functionality">when_all
7499 functionality</a>
7500</h6></div></div></div>
7501<div class="toc"><dl>
7502<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__simple_completion">when_all,
7503 simple completion</a></span></dt>
7504<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values">when_all,
7505 return values</a></span></dt>
7506<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all_until_first_exception">when_all
7507 until first exception</a></span></dt>
7508<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.wait_all__collecting_all_exceptions">wait_all,
7509 collecting all exceptions</a></span></dt>
7510<dt><span class="section"><a href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__heterogeneous_types">when_all,
7511 heterogeneous types</a></span></dt>
7512</dl></div>
7513<div class="section">
7514<div class="titlepage"><div><div><h6 class="title">
7515<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__simple_completion"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__simple_completion" title="when_all, simple completion">when_all,
7516 simple completion</a>
7517</h6></div></div></div>
7518<p>
7519 For the case in which we must wait for <span class="emphasis"><em>all</em></span> task
7520 functions to complete &#8212; but we don't need results (or expect exceptions)
7521 from any of them &#8212; we can write <code class="computeroutput"><span class="identifier">wait_all_simple</span><span class="special">()</span></code> that looks remarkably like <a class="link" href="pooled_fixedsize.html#wait_first_simple"><code class="computeroutput"><span class="identifier">wait_first_simple</span><span class="special">()</span></code></a>. The difference is that
7522 instead of our <a class="link" href="pooled_fixedsize.html#wait_done"><code class="computeroutput"><span class="identifier">Done</span></code></a>
7523 class, we instantiate a <a class="link" href="pooled_fixedsize.html#class_barrier"> <code class="computeroutput">barrier</code></a> and call its <a class="link" href="pooled_fixedsize.html#barrier_wait"> <code class="computeroutput">barrier::wait()</code></a>.
7524 </p>
7525<p>
7526 We initialize the <code class="computeroutput"><span class="identifier">barrier</span></code>
7527 with <code class="computeroutput"><span class="special">(</span><span class="identifier">count</span><span class="special">+</span><span class="number">1</span><span class="special">)</span></code> because we are launching <code class="computeroutput"><span class="identifier">count</span></code> fibers, plus the <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
7528 call within <code class="computeroutput"><span class="identifier">wait_all_simple</span><span class="special">()</span></code> itself.
7529 </p>
7530<p>
7531</p>
7532<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7533<span class="keyword">void</span> <span class="identifier">wait_all_simple</span><span class="special">(</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7534 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7535 <span class="comment">// Initialize a barrier(count+1) because we'll immediately wait on it. We</span>
7536 <span class="comment">// don't want to wake up until 'count' more fibers wait on it. Even though</span>
7537 <span class="comment">// we'll stick around until the last of them completes, use shared_ptr</span>
7538 <span class="comment">// anyway because it's easier to be confident about lifespan issues.</span>
7539 <span class="keyword">auto</span> <span class="identifier">barrier</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">barrier</span> <span class="special">&gt;(</span> <span class="identifier">count</span> <span class="special">+</span> <span class="number">1</span><span class="special">)</span> <span class="special">);</span>
7540 <span class="identifier">wait_all_simple_impl</span><span class="special">(</span> <span class="identifier">barrier</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7541 <span class="identifier">barrier</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span>
7542<span class="special">}</span>
7543</pre>
7544<p>
7545 </p>
7546<p>
7547 As stated above, the only difference between <code class="computeroutput"><span class="identifier">wait_all_simple_impl</span><span class="special">()</span></code> and <a class="link" href="pooled_fixedsize.html#wait_first_simple_impl"><code class="computeroutput"><span class="identifier">wait_first_simple_impl</span><span class="special">()</span></code></a>
7548 is that the former calls <code class="computeroutput"><span class="identifier">barrier</span><span class="special">::</span><span class="identifier">wait</span><span class="special">()</span></code> rather than <code class="computeroutput"><span class="identifier">Done</span><span class="special">::</span><span class="identifier">notify</span><span class="special">()</span></code>:
7549 </p>
7550<p>
7551</p>
7552<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7553<span class="keyword">void</span> <span class="identifier">wait_all_simple_impl</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">barrier</span> <span class="special">&gt;</span> <span class="identifier">barrier</span><span class="special">,</span>
7554 <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7555 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span>
7556 <span class="identifier">std</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span>
7557 <span class="special">[](</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">barrier</span> <span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">barrier</span><span class="special">,</span>
7558 <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">decay</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&amp;</span> <span class="identifier">function</span><span class="special">)</span> <span class="keyword">mutable</span> <span class="special">{</span>
7559 <span class="identifier">function</span><span class="special">();</span>
7560 <span class="identifier">barrier</span><span class="special">-&gt;</span><span class="identifier">wait</span><span class="special">();</span>
7561 <span class="special">},</span>
7562 <span class="identifier">barrier</span><span class="special">,</span>
7563 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">)</span>
7564 <span class="special">)).</span><span class="identifier">detach</span><span class="special">();</span>
7565 <span class="identifier">wait_all_simple_impl</span><span class="special">(</span> <span class="identifier">barrier</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7566<span class="special">}</span>
7567</pre>
7568<p>
7569 </p>
7570<p>
7571 You might call it like this:
7572 </p>
7573<p>
7574</p>
7575<pre class="programlisting"><span class="identifier">wait_all_simple</span><span class="special">(</span>
7576 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"was_long"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7577 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"was_medium"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7578 <span class="special">[](){</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"was_short"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7579</pre>
7580<p>
7581 </p>
7582<p>
7583 Control will not return from the <code class="computeroutput"><span class="identifier">wait_all_simple</span><span class="special">()</span></code> call until the last of its task
7584 functions has completed.
7585 </p>
7586</div>
7587<div class="section">
7588<div class="titlepage"><div><div><h6 class="title">
7589<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values" title="when_all, return values">when_all,
7590 return values</a>
7591</h6></div></div></div>
7592<p>
7593 As soon as we want to collect return values from all the task functions,
7594 we can see right away how to reuse <a class="link" href="pooled_fixedsize.html#wait_first_value"><code class="computeroutput"><span class="identifier">wait_first_value</span><span class="special">()</span></code></a>'s
7595 channel&lt;T&gt; for the purpose. All we have to do is avoid closing
7596 it after the first value!
7597 </p>
7598<p>
7599 But in fact, collecting multiple values raises an interesting question:
7600 do we <span class="emphasis"><em>really</em></span> want to wait until the slowest
7601 of them has arrived? Wouldn't we rather process each result as soon
7602 as it becomes available?
7603 </p>
7604<p>
7605 Fortunately we can present both APIs. Let's define <code class="computeroutput"><span class="identifier">wait_all_values_source</span><span class="special">()</span></code>
7606 to return <code class="computeroutput"><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values.f0" class="footnote">7</a>]</sup>
7607 </p>
7608<p>
7609 <a name="wait_all_values"></a>Given <code class="computeroutput"><span class="identifier">wait_all_values_source</span><span class="special">()</span></code>, it's straightforward to implement
7610 <code class="computeroutput"><span class="identifier">wait_all_values</span><span class="special">()</span></code>:
7611 </p>
7612<p>
7613</p>
7614<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7615<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;</span>
7616<span class="identifier">wait_all_values</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7617 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7618 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7619 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">vector_t</span><span class="special">;</span>
7620 <span class="identifier">vector_t</span> <span class="identifier">results</span><span class="special">;</span>
7621 <span class="identifier">results</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span> <span class="identifier">count</span><span class="special">);</span>
7622
7623 <span class="comment">// get channel</span>
7624 <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span> <span class="special">=</span>
7625 <span class="identifier">wait_all_values_source</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7626 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7627 <span class="comment">// fill results vector</span>
7628 <span class="identifier">return_t</span> <span class="identifier">value</span><span class="special">;</span>
7629 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
7630 <span class="identifier">results</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">value</span><span class="special">);</span>
7631 <span class="special">}</span>
7632 <span class="comment">// return vector to caller</span>
7633 <span class="keyword">return</span> <span class="identifier">results</span><span class="special">;</span>
7634<span class="special">}</span>
7635</pre>
7636<p>
7637 </p>
7638<p>
7639 It might be called like this:
7640 </p>
7641<p>
7642</p>
7643<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">values</span> <span class="special">=</span>
7644 <span class="identifier">wait_all_values</span><span class="special">(</span>
7645 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wav_late"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7646 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wav_middle"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7647 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wav_early"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7648</pre>
7649<p>
7650 </p>
7651<p>
7652 As you can see from the loop in <code class="computeroutput"><span class="identifier">wait_all_values</span><span class="special">()</span></code>, instead of requiring its caller
7653 to count values, we define <code class="computeroutput"><span class="identifier">wait_all_values_source</span><span class="special">()</span></code> to <a class="link" href="pooled_fixedsize.html#unbounded_channel_close"> <code class="computeroutput">unbounded_channel::close()</code></a> the
7654 channel when done. But how do we do that? Each producer fiber is
7655 independent. It has no idea whether it is the last one to <a class="link" href="pooled_fixedsize.html#unbounded_channel_push"> <code class="computeroutput">unbounded_channel::push()</code></a> a
7656 value.
7657 </p>
7658<p>
7659 <a name="wait_nchannel"></a>We can address that problem with a counting
7660 fa&#231;ade for the <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;&gt;</span></code>. In fact, our fa&#231;ade need
7661 only support the producer end of the channel.
7662 </p>
7663<p>
7664</p>
7665<pre class="programlisting"><span class="comment">// Introduce a channel facade that closes the channel once a specific number</span>
7666<span class="comment">// of items has been pushed. This allows an arbitrary consumer to read until</span>
7667<span class="comment">// 'closed' without itself having to count items.</span>
7668<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">&gt;</span>
7669<span class="keyword">class</span> <span class="identifier">nchannel</span> <span class="special">{</span>
7670<span class="keyword">public</span><span class="special">:</span>
7671 <span class="identifier">nchannel</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">cp</span><span class="special">,</span>
7672 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">lm</span><span class="special">):</span>
7673 <span class="identifier">channel_</span><span class="special">(</span> <span class="identifier">cp</span><span class="special">),</span>
7674 <span class="identifier">limit_</span><span class="special">(</span> <span class="identifier">lm</span><span class="special">)</span> <span class="special">{</span>
7675 <span class="identifier">assert</span><span class="special">(</span><span class="identifier">channel_</span><span class="special">);</span>
7676 <span class="keyword">if</span> <span class="special">(</span> <span class="number">0</span> <span class="special">==</span> <span class="identifier">limit_</span><span class="special">)</span> <span class="special">{</span>
7677 <span class="identifier">channel_</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7678 <span class="special">}</span>
7679 <span class="special">}</span>
7680
7681 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span> <span class="identifier">push</span><span class="special">(</span> <span class="identifier">T</span> <span class="special">&amp;&amp;</span> <span class="identifier">va</span><span class="special">)</span> <span class="special">{</span>
7682 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span> <span class="identifier">ok</span> <span class="special">=</span>
7683 <span class="identifier">channel_</span><span class="special">-&gt;</span><span class="identifier">push</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;(</span> <span class="identifier">va</span><span class="special">)</span> <span class="special">);</span>
7684 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">ok</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">&amp;&amp;</span>
7685 <span class="special">--</span><span class="identifier">limit_</span> <span class="special">==</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
7686 <span class="comment">// after the 'limit_'th successful push, close the channel</span>
7687 <span class="identifier">channel_</span><span class="special">-&gt;</span><span class="identifier">close</span><span class="special">();</span>
7688 <span class="special">}</span>
7689 <span class="keyword">return</span> <span class="identifier">ok</span><span class="special">;</span>
7690 <span class="special">}</span>
7691
7692<span class="keyword">private</span><span class="special">:</span>
7693 <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel_</span><span class="special">;</span>
7694 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">limit_</span><span class="special">;</span>
7695<span class="special">};</span>
7696</pre>
7697<p>
7698 </p>
7699<p>
7700 <a name="wait_all_values_source"></a>Armed with <code class="computeroutput"><span class="identifier">nchannel</span><span class="special">&lt;&gt;</span></code>, we can implement <code class="computeroutput"><span class="identifier">wait_all_values_source</span><span class="special">()</span></code>.
7701 It starts just like <a class="link" href="pooled_fixedsize.html#wait_first_value"><code class="computeroutput"><span class="identifier">wait_first_value</span><span class="special">()</span></code></a>.
7702 The difference is that we wrap the <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> with an <code class="computeroutput"><span class="identifier">nchannel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> to pass to the producer fibers.
7703 </p>
7704<p>
7705 Then, of course, instead of popping the first value, closing the
7706 channel and returning it, we simply return the <code class="computeroutput"><span class="identifier">shared_ptr</span><span class="special">&lt;</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&gt;</span></code>.
7707 </p>
7708<p>
7709</p>
7710<pre class="programlisting"><span class="comment">// Return a shared_ptr&lt;unbounded_channel&lt;T&gt;&gt; from which the caller can</span>
7711<span class="comment">// retrieve each new result as it arrives, until 'closed'.</span>
7712<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7713<span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
7714<span class="identifier">wait_all_values_source</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7715 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7716 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7717 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7718 <span class="comment">// make the channel</span>
7719 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7720 <span class="comment">// and make an nchannel facade to close it after 'count' items</span>
7721 <span class="keyword">auto</span> <span class="identifier">ncp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">nchannel</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">);</span>
7722 <span class="comment">// pass that nchannel facade to all the relevant fibers</span>
7723 <span class="identifier">wait_all_values_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">ncp</span><span class="special">,</span>
7724 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7725 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7726 <span class="comment">// then return the channel for consumer</span>
7727 <span class="keyword">return</span> <span class="identifier">channelp</span><span class="special">;</span>
7728<span class="special">}</span>
7729</pre>
7730<p>
7731 </p>
7732<p>
7733 For example:
7734 </p>
7735<p>
7736</p>
7737<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span> <span class="special">=</span>
7738 <span class="identifier">wait_all_values_source</span><span class="special">(</span>
7739 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wavs_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7740 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wavs_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7741 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wavs_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7742<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">value</span><span class="special">;</span>
7743<span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">(</span><span class="identifier">value</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
7744 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_all_values_source() =&gt; '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">value</span>
7745 <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7746<span class="special">}</span>
7747</pre>
7748<p>
7749 </p>
7750<p>
7751 <a name="wait_all_values_impl"></a><code class="computeroutput"><span class="identifier">wait_all_values_impl</span><span class="special">()</span></code> really is just like <a class="link" href="pooled_fixedsize.html#wait_first_value_impl"><code class="computeroutput"><span class="identifier">wait_first_value_impl</span><span class="special">()</span></code></a>
7752 except for the use of <code class="computeroutput"><span class="identifier">nchannel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> rather than <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>:
7753 </p>
7754<p>
7755</p>
7756<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
7757<span class="keyword">void</span> <span class="identifier">wait_all_values_impl</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">nchannel</span><span class="special">&lt;</span> <span class="identifier">T</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span><span class="special">,</span>
7758 <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">)</span> <span class="special">{</span>
7759 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span><span class="special">(</span> <span class="special">[</span><span class="identifier">channel</span><span class="special">,</span> <span class="identifier">function</span><span class="special">](){</span>
7760 <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">push</span><span class="special">(</span><span class="identifier">function</span><span class="special">());</span>
7761 <span class="special">}).</span><span class="identifier">detach</span><span class="special">();</span>
7762<span class="special">}</span>
7763</pre>
7764<p>
7765 </p>
7766</div>
7767<div class="section">
7768<div class="titlepage"><div><div><h6 class="title">
7769<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all_until_first_exception"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all_until_first_exception" title="when_all until first exception">when_all
7770 until first exception</a>
7771</h6></div></div></div>
7772<p>
7773 Naturally, just as with <a class="link" href="pooled_fixedsize.html#wait_first_outcome"><code class="computeroutput"><span class="identifier">wait_first_outcome</span><span class="special">()</span></code></a>,
7774 we can elaborate <a class="link" href="pooled_fixedsize.html#wait_all_values"><code class="computeroutput"><span class="identifier">wait_all_values</span><span class="special">()</span></code></a> and <a class="link" href="pooled_fixedsize.html#wait_all_values_source"><code class="computeroutput"><span class="identifier">wait_all_values_source</span><span class="special">()</span></code></a>
7775 by passing <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">T</span>
7776 <span class="special">&gt;</span></code> instead of plain <code class="computeroutput"><span class="identifier">T</span></code>.
7777 </p>
7778<p>
7779 <a name="wait_all_until_error"></a><code class="computeroutput"><span class="identifier">wait_all_until_error</span><span class="special">()</span></code> pops that <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">T</span>
7780 <span class="special">&gt;</span></code> and calls its <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a>:
7781 </p>
7782<p>
7783</p>
7784<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7785<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;</span>
7786<span class="identifier">wait_all_until_error</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7787 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7788 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7789 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7790 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">vector_t</span><span class="special">;</span>
7791 <span class="identifier">vector_t</span> <span class="identifier">results</span><span class="special">;</span>
7792 <span class="identifier">results</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span> <span class="identifier">count</span><span class="special">);</span>
7793
7794 <span class="comment">// get channel</span>
7795 <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span>
7796 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span><span class="special">(</span>
7797 <span class="identifier">wait_all_until_error_source</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7798 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">)</span> <span class="special">);</span>
7799 <span class="comment">// fill results vector</span>
7800 <span class="identifier">future_t</span> <span class="identifier">future</span><span class="special">;</span>
7801 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">(</span> <span class="identifier">future</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
7802 <span class="identifier">results</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">);</span>
7803 <span class="special">}</span>
7804 <span class="comment">// return vector to caller</span>
7805 <span class="keyword">return</span> <span class="identifier">results</span><span class="special">;</span>
7806<span class="special">}</span>
7807</pre>
7808<p>
7809 </p>
7810<p>
7811 For example:
7812 </p>
7813<p>
7814</p>
7815<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">thrown</span><span class="special">;</span>
7816<span class="keyword">try</span> <span class="special">{</span>
7817 <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">values</span> <span class="special">=</span> <span class="identifier">wait_all_until_error</span><span class="special">(</span>
7818 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"waue_late"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7819 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"waue_middle"</span><span class="special">,</span> <span class="number">100</span><span class="special">,</span> <span class="keyword">true</span><span class="special">);</span> <span class="special">},</span>
7820 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"waue_early"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7821<span class="special">}</span> <span class="keyword">catch</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">e</span><span class="special">)</span> <span class="special">{</span>
7822 <span class="identifier">thrown</span> <span class="special">=</span> <span class="identifier">e</span><span class="special">.</span><span class="identifier">what</span><span class="special">();</span>
7823<span class="special">}</span>
7824<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_all_until_error(fail) threw '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">thrown</span>
7825 <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7826</pre>
7827<p>
7828 </p>
7829<p>
7830 <a name="wait_all_until_error_source"></a>Naturally this complicates
7831 the API for <code class="computeroutput"><span class="identifier">wait_all_until_error_source</span><span class="special">()</span></code>. The caller must both retrieve
7832 a <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;</span>
7833 <span class="identifier">T</span> <span class="special">&gt;</span></code>
7834 and call its <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> method. It would, of course, be
7835 possible to return a fa&#231;ade over the consumer end of the channel
7836 that would implicitly perform the <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> and return a simple <code class="computeroutput"><span class="identifier">T</span></code> (or throw).
7837 </p>
7838<p>
7839 The implementation is just as you would expect. Notice, however,
7840 that we can reuse <a class="link" href="pooled_fixedsize.html#wait_first_outcome_impl"><code class="computeroutput"><span class="identifier">wait_first_outcome_impl</span><span class="special">()</span></code></a>,
7841 passing the <code class="computeroutput"><span class="identifier">nchannel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> rather than <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>.
7842 </p>
7843<p>
7844</p>
7845<pre class="programlisting"><span class="comment">// Return a shared_ptr&lt;unbounded_channel&lt;future&lt;T&gt;&gt;&gt; from which the caller can</span>
7846<span class="comment">// get() each new result as it arrives, until 'closed'.</span>
7847<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7848<span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span>
7849 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span>
7850 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span>
7851 <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="special">&gt;</span>
7852<span class="identifier">wait_all_until_error_source</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7853 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7854 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7855 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7856 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="identifier">channel_t</span><span class="special">;</span>
7857 <span class="comment">// make the channel</span>
7858 <span class="keyword">auto</span> <span class="identifier">channelp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">channel_t</span> <span class="special">&gt;()</span> <span class="special">);</span>
7859 <span class="comment">// and make an nchannel facade to close it after 'count' items</span>
7860 <span class="keyword">auto</span> <span class="identifier">ncp</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">make_shared</span><span class="special">&lt;</span> <span class="identifier">nchannel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="special">&gt;(</span> <span class="identifier">channelp</span><span class="special">,</span> <span class="identifier">count</span><span class="special">)</span> <span class="special">);</span>
7861 <span class="comment">// pass that nchannel facade to all the relevant fibers</span>
7862 <span class="identifier">wait_first_outcome_impl</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;(</span> <span class="identifier">ncp</span><span class="special">,</span>
7863 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7864 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
7865 <span class="comment">// then return the channel for consumer</span>
7866 <span class="keyword">return</span> <span class="identifier">channelp</span><span class="special">;</span>
7867<span class="special">}</span>
7868</pre>
7869<p>
7870 </p>
7871<p>
7872 For example:
7873 </p>
7874<p>
7875</p>
7876<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7877<span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span> <span class="special">=</span>
7878 <span class="identifier">wait_all_until_error_source</span><span class="special">(</span>
7879 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wauess_third"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7880 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wauess_second"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7881 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wauess_first"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7882<span class="identifier">future_t</span> <span class="identifier">future</span><span class="special">;</span>
7883<span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">(</span> <span class="identifier">future</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
7884 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">value</span><span class="special">(</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">);</span>
7885 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_all_until_error_source(success) =&gt; '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">value</span>
7886 <span class="special">&lt;&lt;</span> <span class="string">"'"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7887<span class="special">}</span>
7888</pre>
7889<p>
7890 </p>
7891</div>
7892<div class="section">
7893<div class="titlepage"><div><div><h6 class="title">
7894<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.wait_all__collecting_all_exceptions"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.wait_all__collecting_all_exceptions" title="wait_all, collecting all exceptions">wait_all,
7895 collecting all exceptions</a>
7896</h6></div></div></div>
7897<p>
7898 <a name="wait_all_collect_errors"></a>Given <a class="link" href="pooled_fixedsize.html#wait_all_until_error_source"><code class="computeroutput"><span class="identifier">wait_all_until_error_source</span><span class="special">()</span></code></a>,
7899 it might be more reasonable to make a <code class="computeroutput"><span class="identifier">wait_all_</span><span class="special">...()</span></code> that collects <span class="emphasis"><em>all</em></span>
7900 errors instead of presenting only the first:
7901 </p>
7902<p>
7903</p>
7904<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7905<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="special">&gt;</span>
7906<span class="identifier">wait_all_collect_errors</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">function</span><span class="special">,</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7907 <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">count</span><span class="special">(</span> <span class="number">1</span> <span class="special">+</span> <span class="keyword">sizeof</span> <span class="special">...</span> <span class="special">(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">);</span>
7908 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">result_of</span><span class="special">&lt;</span> <span class="identifier">Fn</span><span class="special">()</span> <span class="special">&gt;::</span><span class="identifier">type</span> <span class="identifier">return_t</span><span class="special">;</span>
7909 <span class="keyword">typedef</span> <span class="keyword">typename</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">future_t</span><span class="special">;</span>
7910 <span class="keyword">typedef</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">return_t</span> <span class="special">&gt;</span> <span class="identifier">vector_t</span><span class="special">;</span>
7911 <span class="identifier">vector_t</span> <span class="identifier">results</span><span class="special">;</span>
7912 <span class="identifier">results</span><span class="special">.</span><span class="identifier">reserve</span><span class="special">(</span> <span class="identifier">count</span><span class="special">);</span>
7913 <span class="identifier">exception_list</span> <span class="identifier">exceptions</span><span class="special">(</span><span class="string">"wait_all_collect_errors() exceptions"</span><span class="special">);</span>
7914
7915 <span class="comment">// get channel</span>
7916 <span class="identifier">std</span><span class="special">::</span><span class="identifier">shared_ptr</span><span class="special">&lt;</span>
7917 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">unbounded_channel</span><span class="special">&lt;</span> <span class="identifier">future_t</span> <span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">channel</span><span class="special">(</span>
7918 <span class="identifier">wait_all_until_error_source</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fn</span> <span class="special">&gt;(</span> <span class="identifier">function</span><span class="special">),</span>
7919 <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">...</span> <span class="special">)</span> <span class="special">);</span>
7920 <span class="comment">// fill results and/or exceptions vectors</span>
7921 <span class="identifier">future_t</span> <span class="identifier">future</span><span class="special">;</span>
7922 <span class="keyword">while</span> <span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">channel_op_status</span><span class="special">::</span><span class="identifier">success</span> <span class="special">==</span> <span class="identifier">channel</span><span class="special">-&gt;</span><span class="identifier">pop</span><span class="special">(</span> <span class="identifier">future</span><span class="special">)</span> <span class="special">)</span> <span class="special">{</span>
7923 <span class="identifier">std</span><span class="special">::</span><span class="identifier">exception_ptr</span> <span class="identifier">exp</span> <span class="special">=</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get_exception_ptr</span><span class="special">();</span>
7924 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">exp</span><span class="special">)</span> <span class="special">{</span>
7925 <span class="identifier">results</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span> <span class="identifier">future</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">);</span>
7926 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
7927 <span class="identifier">exceptions</span><span class="special">.</span><span class="identifier">add</span><span class="special">(</span> <span class="identifier">exp</span><span class="special">);</span>
7928 <span class="special">}</span>
7929 <span class="special">}</span>
7930 <span class="comment">// if there were any exceptions, throw</span>
7931 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">exceptions</span><span class="special">.</span><span class="identifier">size</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
7932 <span class="keyword">throw</span> <span class="identifier">exceptions</span><span class="special">;</span>
7933 <span class="special">}</span>
7934 <span class="comment">// no exceptions: return vector to caller</span>
7935 <span class="keyword">return</span> <span class="identifier">results</span><span class="special">;</span>
7936<span class="special">}</span>
7937</pre>
7938<p>
7939 </p>
7940<p>
7941 The implementation is a simple variation on <a class="link" href="pooled_fixedsize.html#wait_first_success"><code class="computeroutput"><span class="identifier">wait_first_success</span><span class="special">()</span></code></a>,
7942 using the same <a class="link" href="pooled_fixedsize.html#exception_list"><code class="computeroutput"><span class="identifier">exception_list</span></code></a>
7943 exception class.
7944 </p>
7945</div>
7946<div class="section">
7947<div class="titlepage"><div><div><h6 class="title">
7948<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__heterogeneous_types"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__heterogeneous_types" title="when_all, heterogeneous types">when_all,
7949 heterogeneous types</a>
7950</h6></div></div></div>
7951<p>
7952 But what about the case when we must wait for all results of different
7953 types?
7954 </p>
7955<p>
7956 We can present an API that is frankly quite cool. Consider a sample
7957 struct:
7958 </p>
7959<p>
7960</p>
7961<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">Data</span> <span class="special">{</span>
7962 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">str</span><span class="special">;</span>
7963 <span class="keyword">double</span> <span class="identifier">inexact</span><span class="special">;</span>
7964 <span class="keyword">int</span> <span class="identifier">exact</span><span class="special">;</span>
7965
7966 <span class="keyword">friend</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="keyword">operator</span><span class="special">&lt;&lt;(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">ostream</span><span class="special">&amp;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">Data</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">data</span><span class="special">);</span>
7967 <span class="special">...</span>
7968<span class="special">};</span>
7969</pre>
7970<p>
7971 </p>
7972<p>
7973 Let's fill its members from task functions all running concurrently:
7974 </p>
7975<p>
7976</p>
7977<pre class="programlisting"><span class="identifier">Data</span> <span class="identifier">data</span> <span class="special">=</span> <span class="identifier">wait_all_members</span><span class="special">&lt;</span> <span class="identifier">Data</span> <span class="special">&gt;(</span>
7978 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wams_left"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
7979 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="number">3.14</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
7980 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="number">17</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
7981<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_all_members&lt;Data&gt;(success) =&gt; "</span> <span class="special">&lt;&lt;</span> <span class="identifier">data</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
7982</pre>
7983<p>
7984 </p>
7985<p>
7986 Note that for this case, we abandon the notion of capturing the earliest
7987 result first, and so on: we must fill exactly the passed struct in
7988 left-to-right order.
7989 </p>
7990<p>
7991 That permits a beautifully simple implementation:
7992 </p>
7993<p>
7994</p>
7995<pre class="programlisting"><span class="comment">// Explicitly pass Result. This can be any type capable of being initialized</span>
7996<span class="comment">// from the results of the passed functions, such as a struct.</span>
7997<span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Result</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Fns</span> <span class="special">&gt;</span>
7998<span class="identifier">Result</span> <span class="identifier">wait_all_members</span><span class="special">(</span> <span class="identifier">Fns</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">{</span>
7999 <span class="comment">// Run each of the passed functions on a separate fiber, passing all their</span>
8000 <span class="comment">// futures to helper function for processing.</span>
8001 <span class="keyword">return</span> <span class="identifier">wait_all_members_get</span><span class="special">&lt;</span> <span class="identifier">Result</span> <span class="special">&gt;(</span>
8002 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">async</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special">&lt;</span> <span class="identifier">Fns</span> <span class="special">&gt;(</span> <span class="identifier">functions</span><span class="special">)</span> <span class="special">)</span> <span class="special">...</span> <span class="special">);</span>
8003<span class="special">}</span>
8004</pre>
8005<p>
8006 </p>
8007<p>
8008</p>
8009<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Result</span><span class="special">,</span> <span class="keyword">typename</span> <span class="special">...</span> <span class="identifier">Futures</span> <span class="special">&gt;</span>
8010<span class="identifier">Result</span> <span class="identifier">wait_all_members_get</span><span class="special">(</span> <span class="identifier">Futures</span> <span class="special">&amp;&amp;</span> <span class="special">...</span> <span class="identifier">futures</span><span class="special">)</span> <span class="special">{</span>
8011 <span class="comment">// Fetch the results from the passed futures into Result's initializer</span>
8012 <span class="comment">// list. It's true that the get() calls here will block the implicit</span>
8013 <span class="comment">// iteration over futures -- but that doesn't matter because we won't be</span>
8014 <span class="comment">// done until the slowest of them finishes anyway. As results are</span>
8015 <span class="comment">// processed in argument-list order rather than order of completion, the</span>
8016 <span class="comment">// leftmost get() to throw an exception will cause that exception to</span>
8017 <span class="comment">// propagate to the caller.</span>
8018 <span class="keyword">return</span> <span class="identifier">Result</span><span class="special">{</span> <span class="identifier">futures</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">...</span> <span class="special">};</span>
8019<span class="special">}</span>
8020</pre>
8021<p>
8022 </p>
8023<p>
8024 It is tempting to try to implement <code class="computeroutput"><span class="identifier">wait_all_members</span><span class="special">()</span></code> as a one-liner like this:
8025 </p>
8026<pre class="programlisting"><span class="keyword">return</span> <span class="identifier">Result</span><span class="special">{</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">async</span><span class="special">(</span><span class="identifier">functions</span><span class="special">).</span><span class="identifier">get</span><span class="special">()...</span> <span class="special">};</span>
8027</pre>
8028<p>
8029 The trouble with this tactic is that it would serialize all the task
8030 functions. The runtime makes a single pass through <code class="computeroutput"><span class="identifier">functions</span></code>, calling <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a> for
8031 each and then immediately calling <a class="link" href="pooled_fixedsize.html#future_get"> <code class="computeroutput">future::get()</code></a> on its returned
8032 <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>.
8033 That blocks the implicit loop. The above is almost equivalent to
8034 writing:
8035 </p>
8036<pre class="programlisting"><span class="keyword">return</span> <span class="identifier">Result</span><span class="special">{</span> <span class="identifier">functions</span><span class="special">()...</span> <span class="special">};</span>
8037</pre>
8038<p>
8039 in which, of course, there is no concurrency at all.
8040 </p>
8041<p>
8042 Passing the argument pack through a function-call boundary (<code class="computeroutput"><span class="identifier">wait_all_members_get</span><span class="special">()</span></code>)
8043 forces the runtime to make <span class="emphasis"><em>two</em></span> passes: one in
8044 <code class="computeroutput"><span class="identifier">wait_all_members</span><span class="special">()</span></code> to collect the <code class="computeroutput"><span class="identifier">future</span><span class="special">&lt;&gt;</span></code>s from all the <code class="computeroutput"><span class="identifier">async</span><span class="special">()</span></code>
8045 calls, the second in <code class="computeroutput"><span class="identifier">wait_all_members_get</span><span class="special">()</span></code> to fetch each of the results.
8046 </p>
8047<p>
8048 As noted in comments, within the <code class="computeroutput"><span class="identifier">wait_all_members_get</span><span class="special">()</span></code> parameter pack expansion pass,
8049 the blocking behavior of <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> becomes irrelevant. Along the way,
8050 we will hit the <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> for the slowest task function;
8051 after that every subsequent <code class="computeroutput"><span class="identifier">get</span><span class="special">()</span></code> will complete in trivial time.
8052 </p>
8053<p>
8054 By the way, we could also use this same API to fill a vector or other
8055 collection:
8056 </p>
8057<p>
8058</p>
8059<pre class="programlisting"><span class="comment">// If we don't care about obtaining results as soon as they arrive, and we</span>
8060<span class="comment">// prefer a result vector in passed argument order rather than completion</span>
8061<span class="comment">// order, wait_all_members() is another possible implementation of</span>
8062<span class="comment">// wait_all_until_error().</span>
8063<span class="keyword">auto</span> <span class="identifier">strings</span> <span class="special">=</span> <span class="identifier">wait_all_members</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&gt;</span> <span class="special">&gt;(</span>
8064 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wamv_left"</span><span class="special">,</span> <span class="number">150</span><span class="special">);</span> <span class="special">},</span>
8065 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wamv_middle"</span><span class="special">,</span> <span class="number">100</span><span class="special">);</span> <span class="special">},</span>
8066 <span class="special">[](){</span> <span class="keyword">return</span> <span class="identifier">sleeper</span><span class="special">(</span><span class="string">"wamv_right"</span><span class="special">,</span> <span class="number">50</span><span class="special">);</span> <span class="special">});</span>
8067<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"wait_all_members&lt;vector&gt;() =&gt;"</span><span class="special">;</span>
8068<span class="keyword">for</span> <span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">str</span> <span class="special">:</span> <span class="identifier">strings</span><span class="special">)</span> <span class="special">{</span>
8069 <span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">" '"</span> <span class="special">&lt;&lt;</span> <span class="identifier">str</span> <span class="special">&lt;&lt;</span> <span class="string">"'"</span><span class="special">;</span>
8070<span class="special">}</span>
8071<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
8072</pre>
8073<p>
8074 </p>
8075</div>
8076</div>
8077</div>
8078<div class="section">
8079<div class="titlepage"><div><div><h5 class="title">
8080<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration"></a><a name="integration"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.integration" title="Sharing a Thread with Another Main Loop">Sharing
8081 a Thread with Another Main Loop</a>
8082</h5></div></div></div>
8083<h6>
8084<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.h0"></a>
8085 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.integration.overview">Overview</a>
8086 </h6>
8087<p>
8088 As always with cooperative concurrency, it is important not to let any
8089 one fiber monopolize the processor too long: that could <span class="quote">&#8220;<span class="quote">starve</span>&#8221;</span>
8090 other ready fibers. This section discusses a couple of solutions.
8091 </p>
8092<h6>
8093<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.h1"></a>
8094 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.event_driven_program"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.integration.event_driven_program">Event-Driven
8095 Program</a>
8096 </h6>
8097<p>
8098 Consider a classic event-driven program, organized around a main loop
8099 that fetches and dispatches incoming I/O events. You are introducing
8100 <span class="bold"><strong>Boost.Fiber</strong></span> because certain asynchronous
8101 I/O sequences are logically sequential, and for those you want to write
8102 and maintain code that looks and acts sequential.
8103 </p>
8104<p>
8105 You are launching fibers on the application's main thread because certain
8106 of their actions will affect its user interface, and the application's
8107 UI framework permits UI operations only on the main thread. Or perhaps
8108 those fibers need access to main-thread data, and it would be too expensive
8109 in runtime (or development time) to robustly defend every such data item
8110 with thread synchronization primitives.
8111 </p>
8112<p>
8113 You must ensure that the application's main loop <span class="emphasis"><em>itself</em></span>
8114 doesn't monopolize the processor: that the fibers it launches will get
8115 the CPU cycles they need.
8116 </p>
8117<p>
8118 The solution is the same as for any fiber that might claim the CPU for
8119 an extended time: introduce calls to <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_yield"> <code class="computeroutput">this_fiber::yield()</code></a>.
8120 The most straightforward approach is to call <code class="computeroutput"><span class="identifier">yield</span><span class="special">()</span></code> on every iteration of your existing
8121 main loop. In effect, this unifies the application's main loop with
8122 <span class="bold"><strong>Boost.Fiber</strong></span>'s internal main loop. <code class="computeroutput"><span class="identifier">yield</span><span class="special">()</span></code>
8123 allows the fiber manager to run any fibers that have become ready since
8124 the previous iteration of the application's main loop. When these fibers
8125 have had a turn, control passes to the thread's main fiber, which returns
8126 from <code class="computeroutput"><span class="identifier">yield</span><span class="special">()</span></code>
8127 and resumes the application's main loop.
8128 </p>
8129<h6>
8130<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.h2"></a>
8131 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.integration.integrating_with__ulink_url__http___www_boost_org_doc_libs_release_libs_asio_index_html__boost_asio__ulink_"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.integration.integrating_with__ulink_url__http___www_boost_org_doc_libs_release_libs_asio_index_html__boost_asio__ulink_">Integrating
8132 with <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a></a>
8133 </h6>
8134<p>
8135 More challenging is when the application's main loop is embedded in some
8136 other library or framework. Such an application will typically, after
8137 performing all necessary setup, pass control to some form of <code class="computeroutput"><span class="identifier">run</span><span class="special">()</span></code>
8138 function from which control does not return until application shutdown.
8139 </p>
8140<p>
8141 A <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a>
8142 program might call <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service/run.html" target="_top"><code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code></a>
8143 in this way.
8144 </p>
8145<p>
8146 The trick here is to arrange to pass control to <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_yield"> <code class="computeroutput">this_fiber::yield()</code></a> frequently.
8147 You can use an <a href="http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/high_resolution_timer.html" target="_top">Asio
8148 timer</a> for this purpose. Instantiate the timer, arranging to call
8149 a handler function when the timer expires:
8150 </p>
8151<p>
8152 [run_service]
8153 </p>
8154<p>
8155 The handler function calls <code class="computeroutput"><span class="identifier">yield</span><span class="special">()</span></code>, then resets the timer and arranges
8156 to wake up again on expiration:
8157 </p>
8158<p>
8159 [timer_handler]
8160 </p>
8161<p>
8162 Then instead of directly calling <code class="computeroutput"><span class="identifier">io_service</span><span class="special">::</span><span class="identifier">run</span><span class="special">()</span></code>, your application would call the above
8163 <code class="computeroutput"><span class="identifier">run_service</span><span class="special">(</span><span class="identifier">io_service</span><span class="special">&amp;)</span></code>
8164 wrapper.
8165 </p>
8166<p>
8167 Since, in this example, we always pass control to the fiber manager via
8168 <code class="computeroutput"><span class="identifier">yield</span><span class="special">()</span></code>,
8169 the calling fiber is never blocked. Therefore there is always at least
8170 one ready fiber. Therefore the fiber manager never sleeps.
8171 </p>
8172<p>
8173 Using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">seconds</span><span class="special">(</span><span class="number">0</span><span class="special">)</span></code> for
8174 <span class="emphasis"><em>every</em></span> keepalive timer interval would be unfriendly
8175 to other threads. When all I/O is pending and all fibers are blocked,
8176 the io_service and the fiber manager would simply spin the CPU, passing
8177 control back and forth to each other. Resetting the timer for <code class="computeroutput"><span class="identifier">keepalive_iterval</span></code> allows tuning the
8178 responsiveness of this thread relative to others in the same way as when
8179 <span class="bold"><strong>Boost.Fiber</strong></span> is running without <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a>.
8180 </p>
8181<p>
8182 The source code above is found in <a href="../../../../../examples/asio/round_robin.hpp" target="_top">round_robin.hpp</a>.
8183 </p>
8184</div>
8185<div class="section">
8186<div class="titlepage"><div><div><h5 class="title">
8187<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.performance" title="Performance">Performance</a>
8188</h5></div></div></div>
8189<p>
8190 Performance measurements were taken using <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">highresolution_clock</span></code>,
8191 with overhead corrections. The code was compiled using the build options:
8192 variant = release, optimization = speed <sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f0" class="footnote">8</a>]</sup>.
8193 </p>
8194<p>
8195 The columns labeled <span class="bold"><strong>fiber (atomics)</strong></span>
8196 were compiled with default fiber synchronization, capable of synchronizing
8197 fibers running on different threads. The columns labeled <span class="bold"><strong>fiber
8198 (raw)</strong></span> were compiled with <a class="link" href="../../overview.html#cross_thread_sync"><code class="computeroutput"><span class="identifier">BOOST_FIBERS_NO_ATOMICS</span></code></a>.
8199 </p>
8200<div class="table">
8201<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.overhead_of_join__contains_fiber_context_destruction__fiber_stack_deallocation_"></a><p class="title"><b>Table&#160;1.1.&#160;Overhead of join (contains fiber-context destruction, fiber-stack
8202 deallocation)</b></p>
8203<div class="table-contents"><table class="table" summary="Overhead of join (contains fiber-context destruction, fiber-stack
8204 deallocation)">
8205<colgroup>
8206<col>
8207<col>
8208<col>
8209<col>
8210<col>
8211</colgroup>
8212<thead><tr>
8213<th>
8214 <p>
8215 thread
8216 </p>
8217 </th>
8218<th>
8219 <p>
8220 fiber (atomics)
8221 </p>
8222 </th>
8223<th>
8224 <p>
8225 fiber (raw)
8226 </p>
8227 </th>
8228<th>
8229 <p>
8230 tbb
8231 </p>
8232 </th>
8233<th>
8234 <p>
8235 qthread
8236 </p>
8237 </th>
8238</tr></thead>
8239<tbody><tr>
8240<td>
8241 <p>
8242 18 &#181;s
8243 </p>
8244 </td>
8245<td>
8246 <p>
8247 950 ns
8248 </p>
8249 </td>
8250<td>
8251 <p>
8252 900 ns
8253 </p>
8254 </td>
8255<td>
8256 <p>
8257 570 ns
8258 </p>
8259 </td>
8260<td>
8261 <p>
8262 620 ns
8263 </p>
8264 </td>
8265</tr></tbody>
8266</table></div>
8267</div>
8268<br class="table-break"><p>
8269 (from <a href="../../../../../performance/fiber/overhead_join.cpp" target="_top">overhead_join.cpp</a>)
8270 </p>
8271<div class="table">
8272<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.overhead_of_detach"></a><p class="title"><b>Table&#160;1.2.&#160;Overhead of detach</b></p>
8273<div class="table-contents"><table class="table" summary="Overhead of detach">
8274<colgroup>
8275<col>
8276<col>
8277<col>
8278</colgroup>
8279<thead><tr>
8280<th>
8281 <p>
8282 thread
8283 </p>
8284 </th>
8285<th>
8286 <p>
8287 fiber (atomics)
8288 </p>
8289 </th>
8290<th>
8291 <p>
8292 fiber (raw)
8293 </p>
8294 </th>
8295</tr></thead>
8296<tbody><tr>
8297<td>
8298 <p>
8299 126 ns
8300 </p>
8301 </td>
8302<td>
8303 <p>
8304 21 ns
8305 </p>
8306 </td>
8307<td>
8308 <p>
8309 20 ns
8310 </p>
8311 </td>
8312</tr></tbody>
8313</table></div>
8314</div>
8315<br class="table-break"><p>
8316 (from <a href="../../../../../performance/fiber/overhead_detach.cpp" target="_top">overhead_detach.cpp</a>)
8317 </p>
8318<div class="table">
8319<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.overhead_of_yield"></a><p class="title"><b>Table&#160;1.3.&#160;Overhead of yield</b></p>
8320<div class="table-contents"><table class="table" summary="Overhead of yield">
8321<colgroup>
8322<col>
8323<col>
8324<col>
8325</colgroup>
8326<thead><tr>
8327<th>
8328 <p>
8329 thread
8330 </p>
8331 </th>
8332<th>
8333 <p>
8334 fiber (atomics)
8335 </p>
8336 </th>
8337<th>
8338 <p>
8339 fiber (raw)
8340 </p>
8341 </th>
8342</tr></thead>
8343<tbody><tr>
8344<td>
8345 <p>
8346 1.5 &#181;s
8347 </p>
8348 </td>
8349<td>
8350 <p>
8351 310 ns
8352 </p>
8353 </td>
8354<td>
8355 <p>
8356 330 ns
8357 </p>
8358 </td>
8359</tr></tbody>
8360</table></div>
8361</div>
8362<br class="table-break"><p>
8363 (from <a href="../../../../../performance/fiber/overhead_yield.cpp" target="_top">overhead_yield.cpp</a>)
8364 </p>
8365<div class="table">
8366<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.overhead_of_waiting_on_a_future"></a><p class="title"><b>Table&#160;1.4.&#160;Overhead of waiting on a future</b></p>
8367<div class="table-contents"><table class="table" summary="Overhead of waiting on a future">
8368<colgroup>
8369<col>
8370<col>
8371<col>
8372</colgroup>
8373<thead><tr>
8374<th>
8375 <p>
8376 thread
8377 </p>
8378 </th>
8379<th>
8380 <p>
8381 fiber (atomics)
8382 </p>
8383 </th>
8384<th>
8385 <p>
8386 fiber (raw)
8387 </p>
8388 </th>
8389</tr></thead>
8390<tbody><tr>
8391<td>
8392 <p>
8393 16 &#181;s
8394 </p>
8395 </td>
8396<td>
8397 <p>
8398 1.40 &#181;s
8399 </p>
8400 </td>
8401<td>
8402 <p>
8403 1.38 &#181;s
8404 </p>
8405 </td>
8406</tr></tbody>
8407</table></div>
8408</div>
8409<br class="table-break"><p>
8410 (from <a href="../../../../../performance/fiber/overhead_future.cpp" target="_top">overhead_future.cpp</a>)
8411 </p>
8412<div class="table">
8413<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.overhead_of_fiber_creation__contains_fiber_stack_allocation_and_preparation__fiber_context_construction__scheduler_handling_"></a><p class="title"><b>Table&#160;1.5.&#160;Overhead of fiber creation (contains fiber-stack allocation and
8414 preparation, fiber-context construction, scheduler handling)</b></p>
8415<div class="table-contents"><table class="table" summary="Overhead of fiber creation (contains fiber-stack allocation and
8416 preparation, fiber-context construction, scheduler handling)">
8417<colgroup>
8418<col>
8419<col>
8420<col>
8421</colgroup>
8422<thead><tr>
8423<th>
8424 <p>
8425 thread
8426 </p>
8427 </th>
8428<th>
8429 <p>
8430 fiber (atomics)
8431 </p>
8432 </th>
8433<th>
8434 <p>
8435 fiber (raw)
8436 </p>
8437 </th>
8438</tr></thead>
8439<tbody><tr>
8440<td>
8441 <p>
8442 18 &#181;s
8443 </p>
8444 </td>
8445<td>
8446 <p>
8447 450 ns
8448 </p>
8449 </td>
8450<td>
8451 <p>
8452 445 ns
8453 </p>
8454 </td>
8455</tr></tbody>
8456</table></div>
8457</div>
8458<br class="table-break"><p>
8459 (from <a href="../../../../../performance/fiber/overhead_create.cpp" target="_top">overhead_create.cpp</a>)
8460 </p>
8461<div class="table">
8462<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.scaling_of_creating_and_joining"></a><p class="title"><b>Table&#160;1.6.&#160;Scaling of creating and joining</b></p>
8463<div class="table-contents"><table class="table" summary="Scaling of creating and joining">
8464<colgroup>
8465<col>
8466<col>
8467<col>
8468<col>
8469</colgroup>
8470<thead><tr>
8471<th>
8472 <p>
8473 average of
8474 </p>
8475 </th>
8476<th>
8477 <p>
8478 thread
8479 </p>
8480 </th>
8481<th>
8482 <p>
8483 fiber (atomics)
8484 </p>
8485 </th>
8486<th>
8487 <p>
8488 fiber (raw)
8489 </p>
8490 </th>
8491</tr></thead>
8492<tbody>
8493<tr>
8494<td>
8495 <p>
8496 10
8497 </p>
8498 </td>
8499<td>
8500 <p>
8501 8.21 &#181;s
8502 </p>
8503 </td>
8504<td>
8505 <p>
8506 1.96 &#181;s
8507 </p>
8508 </td>
8509<td>
8510 <p>
8511 1.85 &#181;s
8512 </p>
8513 </td>
8514</tr>
8515<tr>
8516<td>
8517 <p>
8518 50
8519 </p>
8520 </td>
8521<td>
8522 <p>
8523 6.67 &#181;s
8524 </p>
8525 </td>
8526<td>
8527 <p>
8528 1.40 &#181;s
8529 </p>
8530 </td>
8531<td>
8532 <p>
8533 1.27 &#181;s
8534 </p>
8535 </td>
8536</tr>
8537<tr>
8538<td>
8539 <p>
8540 100
8541 </p>
8542 </td>
8543<td>
8544 <p>
8545 6.79 &#181;s
8546 </p>
8547 </td>
8548<td>
8549 <p>
8550 1.84 &#181;s
8551 </p>
8552 </td>
8553<td>
8554 <p>
8555 1.81 &#181;s
8556 </p>
8557 </td>
8558</tr>
8559<tr>
8560<td>
8561 <p>
8562 500
8563 </p>
8564 </td>
8565<td>
8566 <p>
8567 8.25 &#181;s
8568 </p>
8569 </td>
8570<td>
8571 <p>
8572 1.13 &#181;s
8573 </p>
8574 </td>
8575<td>
8576 <p>
8577 1.10 &#181;s
8578 </p>
8579 </td>
8580</tr>
8581<tr>
8582<td>
8583 <p>
8584 1000
8585 </p>
8586 </td>
8587<td>
8588 <p>
8589 7.71 &#181;s
8590 </p>
8591 </td>
8592<td>
8593 <p>
8594 1.46 &#181;s
8595 </p>
8596 </td>
8597<td>
8598 <p>
8599 1.26 &#181;s
8600 </p>
8601 </td>
8602</tr>
8603<tr>
8604<td>
8605 <p>
8606 5000
8607 </p>
8608 </td>
8609<td>
8610 <p>
8611 5.67 &#181;s
8612 </p>
8613 </td>
8614<td>
8615 <p>
8616 2.11 &#181;s
8617 </p>
8618 </td>
8619<td>
8620 <p>
8621 1.90 &#181;s
8622 </p>
8623 </td>
8624</tr>
8625<tr>
8626<td>
8627 <p>
8628 10000
8629 </p>
8630 </td>
8631<td>
8632 <p>
8633 5.25 &#181;s
8634 </p>
8635 </td>
8636<td>
8637 <p>
8638 2.36 &#181;s
8639 </p>
8640 </td>
8641<td>
8642 <p>
8643 1.89 &#181;s
8644 </p>
8645 </td>
8646</tr>
8647</tbody>
8648</table></div>
8649</div>
8650<br class="table-break"><p>
8651 (from <a href="../../../../../performance/fiber/scale_join.cpp" target="_top">scale_join.cpp</a>)
8652 </p>
8653<p>
8654 Numbers of the <a href="https://github.com/atemerev/skynet" target="_top">microbenchmark
8655 <span class="emphasis"><em>syknet</em></span></a> from Alexander Temerev <sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f1" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f1" class="footnote">9</a>]</sup>:
8656 </p>
8657<div class="table">
8658<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.performance.performance_of_n_100000_actors_goroutines_fibers"></a><p class="title"><b>Table&#160;1.7.&#160;performance of N=100000 actors/goroutines/fibers</b></p>
8659<div class="table-contents"><table class="table" summary="performance of N=100000 actors/goroutines/fibers">
8660<colgroup>
8661<col>
8662<col>
8663<col>
8664<col>
8665<col>
8666</colgroup>
8667<thead><tr>
8668<th>
8669 <p>
8670 Haskell | stack-1.0.4
8671 </p>
8672 </th>
8673<th>
8674 <p>
8675 fiber (single threaded/raw) | gcc-5.2.1
8676 </p>
8677 </th>
8678<th>
8679 <p>
8680 fiber (single threaded/atomics) | gcc-5.2.1
8681 </p>
8682 </th>
8683<th>
8684 <p>
8685 Erlang | erts-7.0
8686 </p>
8687 </th>
8688<th>
8689 <p>
8690 Go | go1.4.2
8691 </p>
8692 </th>
8693</tr></thead>
8694<tbody><tr>
8695<td>
8696 <p>
8697 58ms - 108ms
8698 </p>
8699 </td>
8700<td>
8701 <p>
8702 205ms - 263ms
8703 </p>
8704 </td>
8705<td>
8706 <p>
8707 221ms - 278ms
8708 </p>
8709 </td>
8710<td>
8711 <p>
8712 237ms- 470ms
8713 </p>
8714 </td>
8715<td>
8716 <p>
8717 614ms - 883ms
8718 </p>
8719 </td>
8720</tr></tbody>
8721</table></div>
8722</div>
8723<br class="table-break">
8724</div>
8725<div class="section">
8726<div class="titlepage"><div><div><h5 class="title">
8727<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom"></a><a name="custom"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom" title="Customization">Customization</a>
8728</h5></div></div></div>
8729<h6>
8730<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.h0"></a>
8731 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.overview"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.overview">Overview</a>
8732 </h6>
8733<p>
8734 As noted in the <a class="link" href="../../scheduling.html#scheduling">Scheduling</a> section,
8735 by default <span class="bold"><strong>Boost.Fiber</strong></span> uses its own
8736 <a class="link" href="../../scheduling.html#class_round_robin"> <code class="computeroutput">round_robin</code></a> scheduler for each thread. To control the
8737 way <span class="bold"><strong>Boost.Fiber</strong></span> schedules ready fibers
8738 on a particular thread, in general you must follow several steps. This
8739 section discusses those steps, whereas <a class="link" href="../../scheduling.html#scheduling">Scheduling</a>
8740 serves as a reference for the classes involved.
8741 </p>
8742<p>
8743 The library's fiber manager keeps track of suspended (blocked) fibers.
8744 Only when a fiber becomes ready to run is it passed to the scheduler.
8745 Of course, if there are fewer than two ready fibers, the scheduler's
8746 job is trivial. Only when there are two or more ready fibers does the
8747 particular scheduler implementation start to influence the overall sequence
8748 of fiber execution.
8749 </p>
8750<p>
8751 In this section we illustrate a simple custom scheduler that honors an
8752 integer fiber priority. We will implement it such that a fiber with higher
8753 priority is preferred over a fiber with lower priority. Any fibers with
8754 equal priority values are serviced on a round-robin basis.
8755 </p>
8756<p>
8757 The full source code for the examples below is found in <a href="../../../../../examples/priority.cpp" target="_top">priority.cpp</a>.
8758 </p>
8759<h6>
8760<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.h1"></a>
8761 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.custom_property_class"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.custom_property_class">Custom
8762 Property Class</a>
8763 </h6>
8764<p>
8765 The first essential point is that we must associate an integer priority
8766 with each fiber.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.custom.f0" class="footnote">10</a>]</sup>
8767 </p>
8768<p>
8769 One might suggest deriving a custom <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> subclass to store
8770 such properties. There are a couple of reasons for the present mechanism.
8771 </p>
8772<div class="orderedlist"><ol class="orderedlist" type="1">
8773<li class="listitem">
8774 <span class="bold"><strong>Boost.Fiber</strong></span> provides a number of
8775 different ways to launch a fiber. (Consider <a class="link" href="pooled_fixedsize.html#fibers_async"> <code class="computeroutput">fibers::async()</code></a>.)
8776 Higher-level libraries might introduce additional such wrapper functions.
8777 A custom scheduler must associate its custom properties with <span class="emphasis"><em>every</em></span>
8778 fiber in the thread, not only the ones explicitly launched by instantiating
8779 a custom <code class="computeroutput"><span class="identifier">fiber</span></code> subclass.
8780 </li>
8781<li class="listitem">
8782 Consider a large existing program that launches fibers in many different
8783 places in the code. We discover a need to introduce a custom scheduler
8784 for a particular thread. If supporting that scheduler's custom properties
8785 required a particular <code class="computeroutput"><span class="identifier">fiber</span></code>
8786 subclass, we would have to hunt down and modify every place that
8787 launches a fiber on that thread.
8788 </li>
8789<li class="listitem">
8790 The <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> class is actually just a handle to internal <a class="link" href="../../scheduling.html#class_context"> <code class="computeroutput">context</code></a> data.
8791 A subclass of <code class="computeroutput"><span class="identifier">fiber</span></code>
8792 would not add data to <code class="computeroutput"><span class="identifier">context</span></code>.
8793 </li>
8794</ol></div>
8795<p>
8796 The present mechanism allows you to <span class="quote">&#8220;<span class="quote">drop in</span>&#8221;</span> a custom scheduler
8797 with its attendant custom properties <span class="emphasis"><em>without</em></span> altering
8798 the rest of your application.
8799 </p>
8800<p>
8801 Instead of deriving a custom scheduler fiber properties subclass from
8802 <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a>, you must instead derive it from <a class="link" href="../../scheduling.html#class_fiber_properties"> <code class="computeroutput">fiber_properties</code></a>.
8803 </p>
8804<p>
8805</p>
8806<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">priority_props</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber_properties</span> <span class="special">{</span>
8807<span class="keyword">public</span><span class="special">:</span>
8808 <span class="identifier">priority_props</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">):</span>
8809 <span class="identifier">fiber_properties</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">),</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c0" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c1"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a>
8810 <span class="identifier">priority_</span><span class="special">(</span> <span class="number">0</span><span class="special">)</span> <span class="special">{</span>
8811 <span class="special">}</span>
8812
8813 <span class="keyword">int</span> <span class="identifier">get_priority</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">{</span>
8814 <span class="keyword">return</span> <span class="identifier">priority_</span><span class="special">;</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c2" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c3"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a>
8815 <span class="special">}</span>
8816
8817 <span class="comment">// Call this method to alter priority, because we must notify</span>
8818 <span class="comment">// priority_scheduler of any change.</span>
8819 <span class="keyword">void</span> <span class="identifier">set_priority</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">p</span><span class="special">)</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c4" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c5"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
8820 <span class="comment">// Of course, it's only worth reshuffling the queue and all if we're</span>
8821 <span class="comment">// actually changing the priority.</span>
8822 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">p</span> <span class="special">!=</span> <span class="identifier">priority_</span><span class="special">)</span> <span class="special">{</span>
8823 <span class="identifier">priority_</span> <span class="special">=</span> <span class="identifier">p</span><span class="special">;</span>
8824 <span class="identifier">notify</span><span class="special">();</span>
8825 <span class="special">}</span>
8826 <span class="special">}</span>
8827
8828 <span class="comment">// The fiber name of course is solely for purposes of this example</span>
8829 <span class="comment">// program; it has nothing to do with implementing scheduler priority.</span>
8830 <span class="comment">// This is a public data member -- not requiring set/get access methods --</span>
8831 <span class="comment">// because we need not inform the scheduler of any change.</span>
8832 <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">;</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c6" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c7"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a>
8833<span class="keyword">private</span><span class="special">:</span>
8834 <span class="keyword">int</span> <span class="identifier">priority_</span><span class="special">;</span>
8835<span class="special">};</span>
8836</pre>
8837<p>
8838 </p>
8839<div class="calloutlist"><table border="0" summary="Callout list">
8840<tr>
8841<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c1"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c0"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
8842<td valign="top" align="left"><p>
8843 Your subclass constructor must accept a <code class="literal"> <a class="link" href="../../scheduling.html#class_context"> <code class="computeroutput">context</code></a>*</code>
8844 and pass it to the <code class="computeroutput"><span class="identifier">fiber_properties</span></code>
8845 constructor.
8846 </p></td>
8847</tr>
8848<tr>
8849<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c3"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c2"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
8850<td valign="top" align="left"><p>
8851 Provide read access methods at your own discretion.
8852 </p></td>
8853</tr>
8854<tr>
8855<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c5"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c4"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
8856<td valign="top" align="left"><p>
8857 It's important to call <code class="computeroutput"><span class="identifier">notify</span><span class="special">()</span></code> on any change in a property that
8858 can affect the scheduler's behavior. Therefore, such modifications
8859 should only be performed through an access method.
8860 </p></td>
8861</tr>
8862<tr>
8863<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c7"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c6"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
8864<td valign="top" align="left"><p>
8865 A property that does not affect the scheduler does not need access
8866 methods.
8867 </p></td>
8868</tr>
8869</table></div>
8870<h6>
8871<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.h2"></a>
8872 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.custom_scheduler_class"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.custom_scheduler_class">Custom
8873 Scheduler Class</a>
8874 </h6>
8875<p>
8876 Now we can derive a custom scheduler from <a class="link" href="../../scheduling.html#class_sched_algorithm_with_properties"> <code class="computeroutput">sched_algorithm_with_properties&lt;&gt;</code></a>,
8877 specifying our custom property class <code class="computeroutput"><span class="identifier">priority_props</span></code>
8878 as the template parameter.
8879 </p>
8880<p>
8881</p>
8882<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">priority_scheduler</span> <span class="special">:</span>
8883 <span class="keyword">public</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">sched_algorithm_with_properties</span><span class="special">&lt;</span> <span class="identifier">priority_props</span> <span class="special">&gt;</span> <span class="special">{</span>
8884<span class="keyword">private</span><span class="special">:</span>
8885 <span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">scheduler</span><span class="special">::</span><span class="identifier">ready_queue_t</span><a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c8" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c9"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> <span class="identifier">rqueue_t</span><span class="special">;</span>
8886
8887 <span class="identifier">rqueue_t</span> <span class="identifier">rqueue_</span><span class="special">;</span>
8888 <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="identifier">mtx_</span><span class="special">{};</span>
8889 <span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span> <span class="identifier">cnd_</span><span class="special">{};</span>
8890 <span class="keyword">bool</span> <span class="identifier">flag_</span><span class="special">{</span> <span class="keyword">false</span> <span class="special">};</span>
8891
8892<span class="keyword">public</span><span class="special">:</span>
8893 <span class="identifier">priority_scheduler</span><span class="special">()</span> <span class="special">:</span>
8894 <span class="identifier">rqueue_</span><span class="special">()</span> <span class="special">{</span>
8895 <span class="special">}</span>
8896
8897 <span class="comment">// For a subclass of sched_algorithm_with_properties&lt;&gt;, it's important to</span>
8898 <span class="comment">// override the correct awakened() overload.</span>
8899 <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c10" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c11"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">awakened</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">priority_props</span> <span class="special">&amp;</span> <span class="identifier">props</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8900 <span class="keyword">int</span> <span class="identifier">ctx_priority</span> <span class="special">=</span> <span class="identifier">props</span><span class="special">.</span><span class="identifier">get_priority</span><span class="special">();</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c12" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c13"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a>
8901 <span class="comment">// With this scheduler, fibers with higher priority values are</span>
8902 <span class="comment">// preferred over fibers with lower priority values. But fibers with</span>
8903 <span class="comment">// equal priority values are processed in round-robin fashion. So when</span>
8904 <span class="comment">// we're handed a new context*, put it at the end of the fibers</span>
8905 <span class="comment">// with that same priority. In other words: search for the first fiber</span>
8906 <span class="comment">// in the queue with LOWER priority, and insert before that one.</span>
8907 <span class="identifier">rqueue_t</span><span class="special">::</span><span class="identifier">iterator</span> <span class="identifier">i</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">find_if</span><span class="special">(</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">begin</span><span class="special">(),</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">end</span><span class="special">(),</span>
8908 <span class="special">[</span><span class="identifier">ctx_priority</span><span class="special">,</span><span class="keyword">this</span><span class="special">](</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">&amp;</span> <span class="identifier">c</span><span class="special">)</span>
8909 <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">properties</span><span class="special">(</span> <span class="special">&amp;</span><span class="identifier">c</span> <span class="special">).</span><span class="identifier">get_priority</span><span class="special">()</span> <span class="special">&lt;</span> <span class="identifier">ctx_priority</span><span class="special">;</span> <span class="special">}));</span>
8910 <span class="comment">// Now, whether or not we found a fiber with lower priority,</span>
8911 <span class="comment">// insert this new fiber here.</span>
8912 <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span> <span class="identifier">i</span><span class="special">,</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">);</span>
8913 <span class="special">}</span>
8914
8915 <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c14" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c15"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a><span class="keyword">virtual</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">pick_next</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8916 <span class="comment">// if ready queue is empty, just tell caller</span>
8917 <span class="keyword">if</span> <span class="special">(</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">()</span> <span class="special">)</span> <span class="special">{</span>
8918 <span class="keyword">return</span> <span class="keyword">nullptr</span><span class="special">;</span>
8919 <span class="special">}</span>
8920 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">(</span> <span class="special">&amp;</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">front</span><span class="special">()</span> <span class="special">);</span>
8921 <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">pop_front</span><span class="special">();</span>
8922 <span class="keyword">return</span> <span class="identifier">ctx</span><span class="special">;</span>
8923 <span class="special">}</span>
8924
8925 <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c16" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c17"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a><span class="keyword">virtual</span> <span class="keyword">bool</span> <span class="identifier">has_ready_fibers</span><span class="special">()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8926 <span class="keyword">return</span> <span class="special">!</span> <span class="identifier">rqueue_</span><span class="special">.</span><span class="identifier">empty</span><span class="special">();</span>
8927 <span class="special">}</span>
8928
8929 <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c18" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c19"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a><span class="keyword">virtual</span> <span class="keyword">void</span> <span class="identifier">property_change</span><span class="special">(</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">context</span> <span class="special">*</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">priority_props</span> <span class="special">&amp;</span> <span class="identifier">props</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8930 <span class="comment">// Although our priority_props class defines multiple properties, only</span>
8931 <span class="comment">// one of them (priority) actually calls notify() when changed. The</span>
8932 <span class="comment">// point of a property_change() override is to reshuffle the ready</span>
8933 <span class="comment">// queue according to the updated priority value.</span>
8934
8935 <span class="comment">// 'ctx' might not be in our queue at all, if caller is changing the</span>
8936 <span class="comment">// priority of (say) the running fiber. If it's not there, no need to</span>
8937 <span class="comment">// move it: we'll handle it next time it hits awakened().</span>
8938 <span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span> <span class="identifier">ctx</span><span class="special">-&gt;</span><span class="identifier">ready_is_linked</span><span class="special">())</span> <span class="special">{</span> <a class="co" name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c20" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c21"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a>
8939 <span class="keyword">return</span><span class="special">;</span>
8940 <span class="special">}</span>
8941
8942 <span class="comment">// Found ctx: unlink it</span>
8943 <span class="identifier">ctx</span><span class="special">-&gt;</span><span class="identifier">ready_unlink</span><span class="special">();</span>
8944
8945 <span class="comment">// Here we know that ctx was in our ready queue, but we've unlinked</span>
8946 <span class="comment">// it. We happen to have a method that will (re-)add a context* to the</span>
8947 <span class="comment">// right place in the ready queue.</span>
8948 <span class="identifier">awakened</span><span class="special">(</span> <span class="identifier">ctx</span><span class="special">,</span> <span class="identifier">props</span><span class="special">);</span>
8949 <span class="special">}</span>
8950
8951 <span class="keyword">void</span> <span class="identifier">suspend_until</span><span class="special">(</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">steady_clock</span><span class="special">::</span><span class="identifier">time_point</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">time_point</span><span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8952 <span class="keyword">if</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">chrono</span><span class="special">::</span><span class="identifier">steady_clock</span><span class="special">::</span><span class="identifier">time_point</span><span class="special">::</span><span class="identifier">max</span><span class="special">)()</span> <span class="special">==</span> <span class="identifier">time_point</span><span class="special">)</span> <span class="special">{</span>
8953 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_</span><span class="special">);</span>
8954 <span class="identifier">cnd_</span><span class="special">.</span><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](){</span> <span class="keyword">return</span> <span class="identifier">flag_</span><span class="special">;</span> <span class="special">});</span>
8955 <span class="identifier">flag_</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
8956 <span class="special">}</span> <span class="keyword">else</span> <span class="special">{</span>
8957 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_</span><span class="special">);</span>
8958 <span class="identifier">cnd_</span><span class="special">.</span><span class="identifier">wait_until</span><span class="special">(</span> <span class="identifier">lk</span><span class="special">,</span> <span class="identifier">time_point</span><span class="special">,</span> <span class="special">[</span><span class="keyword">this</span><span class="special">](){</span> <span class="keyword">return</span> <span class="identifier">flag_</span><span class="special">;</span> <span class="special">});</span>
8959 <span class="identifier">flag_</span> <span class="special">=</span> <span class="keyword">false</span><span class="special">;</span>
8960 <span class="special">}</span>
8961 <span class="special">}</span>
8962
8963 <span class="keyword">void</span> <span class="identifier">notify</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">{</span>
8964 <span class="identifier">std</span><span class="special">::</span><span class="identifier">unique_lock</span><span class="special">&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">mutex</span> <span class="special">&gt;</span> <span class="identifier">lk</span><span class="special">(</span> <span class="identifier">mtx_</span><span class="special">);</span>
8965 <span class="identifier">flag_</span> <span class="special">=</span> <span class="keyword">true</span><span class="special">;</span>
8966 <span class="identifier">lk</span><span class="special">.</span><span class="identifier">unlock</span><span class="special">();</span>
8967 <span class="identifier">cnd_</span><span class="special">.</span><span class="identifier">notify_all</span><span class="special">();</span>
8968 <span class="special">}</span>
8969<span class="special">};</span>
8970</pre>
8971<p>
8972 </p>
8973<div class="calloutlist"><table border="0" summary="Callout list">
8974<tr>
8975<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c9"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c8"><img src="../../../../../../../doc/src/images/callouts/1.png" alt="1" border="0"></a> </p></td>
8976<td valign="top" align="left"><p>
8977 See <a class="link" href="../../scheduling.html#ready_queue_t">ready_queue_t</a>.
8978 </p></td>
8979</tr>
8980<tr>
8981<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c11"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c10"><img src="../../../../../../../doc/src/images/callouts/2.png" alt="2" border="0"></a> </p></td>
8982<td valign="top" align="left"><p>
8983 You must override the <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_awakened"> <code class="computeroutput">sched_algorithm_with_properties::awakened()</code></a>
8984 method.
8985 This is how your scheduler receives notification of a fiber that
8986 has become ready to run.
8987 </p></td>
8988</tr>
8989<tr>
8990<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c13"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c12"><img src="../../../../../../../doc/src/images/callouts/3.png" alt="3" border="0"></a> </p></td>
8991<td valign="top" align="left"><p>
8992 <code class="computeroutput"><span class="identifier">props</span></code> is the instance
8993 of priority_props associated with the passed fiber <code class="computeroutput"><span class="identifier">ctx</span></code>.
8994 </p></td>
8995</tr>
8996<tr>
8997<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c15"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c14"><img src="../../../../../../../doc/src/images/callouts/4.png" alt="4" border="0"></a> </p></td>
8998<td valign="top" align="left"><p>
8999 You must override the <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_pick_next"> <code class="computeroutput">sched_algorithm_with_properties::pick_next()</code></a>
9000 method.
9001 This is how your scheduler actually advises the fiber manager of
9002 the next fiber to run.
9003 </p></td>
9004</tr>
9005<tr>
9006<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c17"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c16"><img src="../../../../../../../doc/src/images/callouts/5.png" alt="5" border="0"></a> </p></td>
9007<td valign="top" align="left"><p>
9008 You must override <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_has_ready_fibers"> <code class="computeroutput">sched_algorithm_with_properties::has_ready_fibers()</code></a>
9009 to
9010 inform the fiber manager of the state of your ready queue.
9011 </p></td>
9012</tr>
9013<tr>
9014<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c19"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c18"><img src="../../../../../../../doc/src/images/callouts/6.png" alt="6" border="0"></a> </p></td>
9015<td valign="top" align="left"><p>
9016 Overriding <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_property_change"> <code class="computeroutput">sched_algorithm_with_properties::property_change()</code></a>
9017 is
9018 optional. This override handles the case in which the running fiber
9019 changes the priority of another ready fiber: a fiber already in our
9020 queue. In that case, move the updated fiber within the queue.
9021 </p></td>
9022</tr>
9023<tr>
9024<td width="5%" valign="top" align="left"><p><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c21"></a><a href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.c20"><img src="../../../../../../../doc/src/images/callouts/7.png" alt="7" border="0"></a> </p></td>
9025<td valign="top" align="left"><p>
9026 Your <code class="computeroutput"><span class="identifier">property_change</span><span class="special">()</span></code> override must be able to handle
9027 the case in which the passed <code class="computeroutput"><span class="identifier">ctx</span></code>
9028 is not in your ready queue. It might be running, or it might be blocked.
9029 </p></td>
9030</tr>
9031</table></div>
9032<p>
9033 Our example <code class="computeroutput"><span class="identifier">priority_scheduler</span></code>
9034 doesn't override <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_new_properties"> <code class="computeroutput">sched_algorithm_with_properties::new_properties()</code></a>:
9035 we're content with allocating <code class="computeroutput"><span class="identifier">priority_props</span></code>
9036 instances on the heap.
9037 </p>
9038<h6>
9039<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.h3"></a>
9040 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.replace_default_scheduler"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.replace_default_scheduler">Replace
9041 Default Scheduler</a>
9042 </h6>
9043<p>
9044 You must call <a class="link" href="../../fiber_mgmt/fiber.html#use_scheduling_algorithm"> <code class="computeroutput">use_scheduling_algorithm()</code></a> at the
9045 start of each thread on which you want <span class="bold"><strong>Boost.Fiber</strong></span>
9046 to use your custom scheduler rather than its own default <a class="link" href="../../scheduling.html#class_round_robin"> <code class="computeroutput">round_robin</code></a>.
9047 Specifically, you must call <code class="computeroutput"><span class="identifier">use_scheduling_algorithm</span><span class="special">()</span></code> before performing any other <span class="bold"><strong>Boost.Fiber</strong></span> operations on that thread.
9048 </p>
9049<p>
9050</p>
9051<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">main</span><span class="special">(</span> <span class="keyword">int</span> <span class="identifier">argc</span><span class="special">,</span> <span class="keyword">char</span> <span class="special">*</span><span class="identifier">argv</span><span class="special">[])</span> <span class="special">{</span>
9052 <span class="comment">// make sure we use our priority_scheduler rather than default round_robin</span>
9053 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">use_scheduling_algorithm</span><span class="special">&lt;</span> <span class="identifier">priority_scheduler</span> <span class="special">&gt;();</span>
9054 <span class="special">...</span>
9055<span class="special">}</span>
9056</pre>
9057<p>
9058 </p>
9059<h6>
9060<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.h4"></a>
9061 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.custom.use_properties"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.use_properties">Use
9062 Properties</a>
9063 </h6>
9064<p>
9065 The running fiber can access its own <a class="link" href="../../scheduling.html#class_fiber_properties"> <code class="computeroutput">fiber_properties</code></a> subclass
9066 instance by calling <a class="link" href="../../fiber_mgmt/this_fiber.html#this_fiber_properties"> <code class="computeroutput">this_fiber::properties()</code></a>. Although
9067 <code class="computeroutput"><span class="identifier">properties</span><span class="special">&lt;&gt;()</span></code>
9068 is a nullary function, you must pass, as a template parameter, the <code class="computeroutput"><span class="identifier">fiber_properties</span></code> subclass.
9069 </p>
9070<p>
9071</p>
9072<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">properties</span><span class="special">&lt;</span> <span class="identifier">priority_props</span> <span class="special">&gt;().</span><span class="identifier">name</span> <span class="special">=</span> <span class="string">"main"</span><span class="special">;</span>
9073</pre>
9074<p>
9075 </p>
9076<p>
9077 Given a <a class="link" href="../../fiber_mgmt/fiber.html#class_fiber"> <code class="computeroutput">fiber</code></a> instance still connected with a running fiber
9078 (that is, not <a class="link" href="../../fiber_mgmt/fiber.html#fiber_detach"> <code class="computeroutput">fiber::detach()</code></a>ed), you may access that fiber's
9079 properties using <a class="link" href="../../fiber_mgmt/fiber.html#fiber_properties"> <code class="computeroutput">fiber::properties()</code></a>. As with <code class="computeroutput"><span class="identifier">this_fiber</span><span class="special">::</span><span class="identifier">properties</span><span class="special">&lt;&gt;()</span></code>,
9080 you must pass your <code class="computeroutput"><span class="identifier">fiber_properties</span></code>
9081 subclass as the template parameter.
9082 </p>
9083<p>
9084</p>
9085<pre class="programlisting"><span class="keyword">template</span><span class="special">&lt;</span> <span class="keyword">typename</span> <span class="identifier">Fn</span> <span class="special">&gt;</span>
9086<span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">launch</span><span class="special">(</span> <span class="identifier">Fn</span> <span class="special">&amp;&amp;</span> <span class="identifier">func</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">name</span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">priority</span><span class="special">)</span> <span class="special">{</span>
9087 <span class="identifier">boost</span><span class="special">::</span><span class="identifier">fibers</span><span class="special">::</span><span class="identifier">fiber</span> <span class="identifier">fiber</span><span class="special">(</span> <span class="identifier">func</span><span class="special">);</span>
9088 <span class="identifier">priority_props</span> <span class="special">&amp;</span> <span class="identifier">props</span><span class="special">(</span> <span class="identifier">fiber</span><span class="special">.</span><span class="identifier">properties</span><span class="special">&lt;</span> <span class="identifier">priority_props</span> <span class="special">&gt;()</span> <span class="special">);</span>
9089 <span class="identifier">props</span><span class="special">.</span><span class="identifier">name</span> <span class="special">=</span> <span class="identifier">name</span><span class="special">;</span>
9090 <span class="identifier">props</span><span class="special">.</span><span class="identifier">set_priority</span><span class="special">(</span> <span class="identifier">priority</span><span class="special">);</span>
9091 <span class="keyword">return</span> <span class="identifier">fiber</span><span class="special">;</span>
9092<span class="special">}</span>
9093</pre>
9094<p>
9095 </p>
9096<p>
9097 Launching a new fiber schedules that fiber as ready, but does <span class="emphasis"><em>not</em></span>
9098 immediately enter its <span class="emphasis"><em>fiber-function</em></span>. The current
9099 fiber retains control until it blocks (or yields, or terminates) for
9100 some other reason. As shown in the <code class="computeroutput"><span class="identifier">launch</span><span class="special">()</span></code> function above, it is reasonable to
9101 launch a fiber and immediately set relevant properties -- such as, for
9102 instance, its priority. Your custom scheduler can then make use of this
9103 information next time the fiber manager calls <a class="link" href="../../scheduling.html#sched_algorithm_with_properties_pick_next"> <code class="computeroutput">sched_algorithm_with_properties::pick_next()</code></a>.
9104 </p>
9105</div>
9106<div class="section">
9107<div class="titlepage"><div><div><h5 class="title">
9108<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale" title="Rationale">Rationale</a>
9109</h5></div></div></div>
9110<h6>
9111<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h0"></a>
9112 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.distinction_between_coroutines_and_fibers"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.distinction_between_coroutines_and_fibers">distinction
9113 between coroutines and fibers</a>
9114 </h6>
9115<p>
9116 The fiber library extends the coroutine library by adding a scheduler
9117 and synchronization mechanisms.
9118 </p>
9119<div class="itemizedlist"><ul class="itemizedlist" type="disc">
9120<li class="listitem">
9121 a coroutine yields
9122 </li>
9123<li class="listitem">
9124 a fiber blocks
9125 </li>
9126</ul></div>
9127<p>
9128 When a coroutine yields, it passes control directly to its caller (or,
9129 in the case of symmetric coroutines, a designated other coroutine). When
9130 a fiber blocks, it implicitly passes control to the fiber scheduler.
9131 Coroutines have no scheduler because they need no scheduler.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f0" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f0" class="footnote">11</a>]</sup>.
9132 </p>
9133<h6>
9134<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h1"></a>
9135 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.what_about_transactional_memory"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.what_about_transactional_memory">what
9136 about transactional memory</a>
9137 </h6>
9138<p>
9139 GCC supports transactional memory since version 4.7. Unfortunately tests
9140 show that transactional memory is slower (ca. 4x) than spinlocks using
9141 atomics. Once transactional memory is improved (supporting hybrid tm),
9142 spinlocks will be replaced by __transaction_atomic{} statements surrounding
9143 the critical sections.
9144 </p>
9145<h6>
9146<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h2"></a>
9147 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.synchronization_between_fibers_running_in_different_threads"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.synchronization_between_fibers_running_in_different_threads">synchronization
9148 between fibers running in different threads</a>
9149 </h6>
9150<p>
9151 Synchronization classes from <a href="http://www.boost.org/doc/libs/release/libs/thread/index.html" target="_top">Boost.Thread</a>
9152 block the entire thread. In contrast, the synchronization classes from
9153 <span class="bold"><strong>Boost.Fiber</strong></span> block only specific fibers,
9154 so that the scheduler can still keep the thread busy running other fibers
9155 in the meantime. The synchronization classes from <span class="bold"><strong>Boost.Fiber</strong></span>
9156 are designed to be thread-safe, i.e. it is possible to synchronize fibers
9157 running in different threads as well as fibers running in the same thread.
9158 (However, there is a build option to disable cross-thread fiber synchronization
9159 support; see <a class="link" href="../../overview.html#cross_thread_sync">this description</a>.)
9160 </p>
9161<a name="spurious_wakeup"></a><h6>
9162<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h3"></a>
9163 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.spurious_wakeup"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.spurious_wakeup">spurious
9164 wakeup</a>
9165 </h6>
9166<p>
9167 Spurious wakeup can happen when using <a href="http://en.cppreference.com/w/cpp/thread/condition_variable" target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span></code></a>: the condition
9168 variable appears to be have been signaled while the awaited condition
9169 may still be false. Spurious wakeup can happen repeatedly and is caused
9170 on some multiprocessor systems where making <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span></code>
9171 wakeup completely predictable would slow down all <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">condition_variable</span></code>
9172 operations.<sup>[<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f1" href="#ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f1" class="footnote">12</a>]</sup>
9173 </p>
9174<p>
9175 <a class="link" href="pooled_fixedsize.html#class_condition_variable"> <code class="computeroutput">condition_variable</code></a> is not subject to spurious
9176 wakeup. Nonetheless it is prudent to test the business-logic condition
9177 in a <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
9178 loop &#8212; or, equivalently, use one of the <code class="computeroutput"><span class="identifier">wait</span><span class="special">(</span> <span class="identifier">lock</span><span class="special">,</span> <span class="identifier">predicate</span>
9179 <span class="special">)</span></code> overloads.
9180 </p>
9181<p>
9182 See also <a class="link" href="pooled_fixedsize.html#condition_variable_spurious_wakeups">No Spurious
9183 Wakeups</a>.
9184 </p>
9185<h6>
9186<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h4"></a>
9187 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.migrating_fibers_between_threads"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.migrating_fibers_between_threads">migrating
9188 fibers between threads</a>
9189 </h6>
9190<p>
9191 Support for migrating fibers between threads has been integrated. The
9192 user-defined scheduler must call <a class="link" href="../../scheduling.html#context_migrate"> <code class="computeroutput">context::migrate()</code></a> on
9193 a fiber-context on the destination thread, passing <code class="computeroutput"><span class="identifier">migrate</span><span class="special">()</span></code> the fiber-context to migrate. (For
9194 more information about custom schedulers, see <a class="link" href="pooled_fixedsize.html#custom">Customization</a>.)
9195 Examples <code class="computeroutput"><span class="identifier">work_sharing</span></code>
9196 and <code class="computeroutput"><span class="identifier">work_stealing</span></code> in
9197 directory <code class="computeroutput"><span class="identifier">examples</span></code> might
9198 be used as a blueprint.
9199 </p>
9200<p>
9201 See also <a class="link" href="pooled_fixedsize.html#migration">Migrating fibers between threads</a>.
9202 </p>
9203<h6>
9204<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h5"></a>
9205 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.support_for_boost_asio"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.support_for_boost_asio">support
9206 for Boost.Asio</a>
9207 </h6>
9208<p>
9209 Support for <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a>'s
9210 <span class="emphasis"><em>async-result</em></span> is not part of the official API. However,
9211 to integrate with a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">io_service</span></code>,
9212 see <a class="link" href="pooled_fixedsize.html#integration">Sharing a Thread with Another Main Loop</a>.
9213 To interface smoothly with an arbitrary Asio async I/O operation, see
9214 <a class="link" href="pooled_fixedsize.html#callbacks_asio">Then There's <a href="http://www.boost.org/doc/libs/release/libs/asio/index.html" target="_top">Boost.Asio</a></a>.
9215 </p>
9216<h6>
9217<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h6"></a>
9218 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.tested_compilers"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.tested_compilers">tested
9219 compilers</a>
9220 </h6>
9221<p>
9222 The library was tested with GCC-5.1.1, Clang-3.6.0 and MSVC-14.0 in c++11-mode.
9223 </p>
9224<h6>
9225<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.h7"></a>
9226 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.supported_architectures"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.supported_architectures">supported
9227 architectures</a>
9228 </h6>
9229<p>
9230 <span class="bold"><strong>Boost.Fiber</strong></span> depends on <a href="http://www.boost.org/doc/libs/release/libs/context/index.html" target="_top">Boost.Context</a>
9231 - the list of supported architectures can be found <a href="http://www.boost.org/doc/libs/release/libs/context/doc/html/context/architectures.html" target="_top">here</a>.
9232 </p>
9233</div>
9234<div class="section">
9235<div class="titlepage"><div><div><h5 class="title">
9236<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.acknowledgements"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.acknowledgements" title="Acknowledgments">Acknowledgments</a>
9237</h5></div></div></div>
9238<p>
9239 I'd like to thank Agust&#237;n Berg&#233;, Eugene Yakubovich, Giovanni Piero
9240 Deretta and especially Nat Goodspeed.
9241 </p>
9242</div>
9243<div class="section">
9244<div class="titlepage"><div><div><h5 class="title">
9245<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.installing"></a><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.installing" title="Appendix: Installing and Running Tests">Appendix:
9246 Installing and Running Tests</a>
9247</h5></div></div></div>
9248<h6>
9249<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.installing.h0"></a>
9250 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.installing.installing_the_fiber_library"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.installing.installing_the_fiber_library">Installing
9251 the Fiber library</a>
9252 </h6>
9253<p>
9254 As Fiber is not yet officially part of Boost, it is necessary to embed
9255 it in an existing <a href="http://www.boost.org/users/download/" target="_top">Boost
9256 source tree</a>.
9257 </p>
9258<p>
9259 The <a href="https://github.com/olk/boost-fiber/archive/master.zip" target="_top">downloaded
9260 Fiber library</a> can be placed into an existing Boost source tree
9261 by moving the top-level Fiber directory to <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span></code>
9262 under the top-level Boost directory, then further moving <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code> (in other words, the Fiber library's
9263 <code class="computeroutput"><span class="identifier">include</span><span class="special">/</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code> directory) to <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code>
9264 under the top-level Boost directory.
9265 </p>
9266<p>
9267 On a Posix system such as Linux or OS X, you may use symlinks instead.
9268 </p>
9269<p>
9270 Create a symlink from the Boost directory's <code class="computeroutput"><span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span></code>
9271 to the top-level Fiber directory, e.g.:
9272 </p>
9273<pre class="programlisting"><span class="identifier">cd</span> <span class="special">~/</span><span class="identifier">boost_1_61_0</span>
9274<span class="identifier">ln</span> <span class="special">-</span><span class="identifier">s</span> <span class="special">~/</span><span class="identifier">boost</span><span class="special">-</span><span class="identifier">fiber</span><span class="special">-</span><span class="identifier">master</span> <span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span>
9275</pre>
9276<p>
9277 Then create a symlink from the Boost directory's <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code>
9278 to the Fiber library's <code class="computeroutput"><span class="identifier">include</span><span class="special">/</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code>
9279 directory:
9280 </p>
9281<pre class="programlisting"><span class="identifier">cd</span> <span class="identifier">boost</span>
9282<span class="identifier">ln</span> <span class="special">-</span><span class="identifier">s</span> <span class="special">../</span><span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">include</span><span class="special">/</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span> <span class="identifier">fiber</span>
9283</pre>
9284<p>
9285 For some versions of the Boost.Build system, it was important to use
9286 a relative symlink of that form for <code class="computeroutput"><span class="identifier">boost</span><span class="special">/</span><span class="identifier">fiber</span></code>.
9287 </p>
9288<a name="tests"></a><h6>
9289<a name="fiber.stack.protected_fixedsize.pooled_fixedsize.installing.h1"></a>
9290 <span><a name="fiber.stack.protected_fixedsize.pooled_fixedsize.installing.running_tests"></a></span><a class="link" href="pooled_fixedsize.html#fiber.stack.protected_fixedsize.pooled_fixedsize.installing.running_tests">Running
9291 Tests</a>
9292 </h6>
9293<p>
9294 Once the Fiber library has been overlaid (or symlinked) into the Boost
9295 source tree this way, the Boost.Build system can build it like any other
9296 Boost library. In particular:
9297 </p>
9298<pre class="programlisting"><span class="identifier">cd</span> <span class="special">~/</span><span class="identifier">boost_1_61_0</span>
9299<span class="special">./</span><span class="identifier">bootstrap</span><span class="special">.</span><span class="identifier">sh</span>
9300<span class="special">./</span><span class="identifier">b2</span> <span class="identifier">libs</span><span class="special">/</span><span class="identifier">fiber</span><span class="special">/</span><span class="identifier">test</span>
9301</pre>
9302<p>
9303 On Windows, the commands would look more like:
9304 </p>
9305<pre class="programlisting"><span class="identifier">cd</span> <span class="special">/</span><span class="identifier">D</span> <span class="special">%</span><span class="identifier">HOMEDRIVE</span><span class="special">%%</span><span class="identifier">HOMEPATH</span><span class="special">%\</span><span class="identifier">boost_1_61_0</span>
9306<span class="identifier">bootstrap</span>
9307<span class="identifier">b2</span> <span class="identifier">libs</span><span class="special">\</span><span class="identifier">fiber</span><span class="special">\</span><span class="identifier">test</span>
9308</pre>
9309</div>
9310<div class="footnotes">
9311<br><hr width="100" align="left">
9312<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.synchronization.barriers.f0" class="para">2</a>] </sup>
9313 The current implementation wakes fibers in FIFO order: the first
9314 to call <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code>
9315 wakes first, and so forth. But it is perilous to rely on the order
9316 in which the various fibers will reach the <code class="computeroutput"><span class="identifier">wait</span><span class="special">()</span></code> call.
9317 </p></div>
9318<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f0" class="para">3</a>] </sup>
9319 The <span class="quote">&#8220;<span class="quote">main</span>&#8221;</span> fiber on each thread, that is, the fiber on
9320 which the thread is launched, cannot migrate to any other thread. Also
9321 <span class="bold"><strong>Boost.Fiber</strong></span> implicitly creates a dispatcher
9322 fiber for each thread &#8212; this cannot migrate either.
9323 </p></div>
9324<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f1" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.migration.f1" class="para">4</a>] </sup>
9325 Of course it would be problematic to migrate a fiber that relies on
9326 <a class="link" href="../../overview.html#thread_local_storage">thread-local storage</a>.
9327 </p></div>
9328<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f0" class="para">5</a>] </sup>
9329 This mechanism has been proposed as a conventional way to allow the
9330 caller of an async function to specify completion handling: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4045.pdf" target="_top">N4045</a>.
9331 </p></div>
9332<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f1" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.callbacks.f1" class="para">6</a>] </sup>
9333 per <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4045.pdf" target="_top">N4045</a>
9334 </p></div>
9335<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.when_any.when_all_functionality.when_all__return_values.f0" class="para">7</a>] </sup>
9336 We could have used either <a class="link" href="pooled_fixedsize.html#class_bounded_channel"> <code class="computeroutput">bounded_channel&lt;&gt;</code></a> or
9337 <a class="link" href="pooled_fixedsize.html#class_unbounded_channel"> <code class="computeroutput">unbounded_channel&lt;&gt;</code></a>. We chose <code class="computeroutput"><span class="identifier">unbounded_channel</span><span class="special">&lt;&gt;</span></code>
9338 on the assumption that its simpler semantics imply a cheaper implementation.
9339 </p></div>
9340<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f0" class="para">8</a>] </sup>
9341 Intel Core2 Q6700, x86_64, 3GHz
9342 </p></div>
9343<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f1" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.performance.f1" class="para">9</a>] </sup>
9344 Intel Core2 Q6700, x86_64, 3GHz
9345 </p></div>
9346<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.custom.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.custom.f0" class="para">10</a>] </sup>
9347 A previous version of the Fiber library implicitly tracked an int priority
9348 for each fiber, even though the default scheduler ignored it. This
9349 has been dropped, since the library now supports arbitrary scheduler-specific
9350 fiber properties.
9351 </p></div>
9352<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f0" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f0" class="para">11</a>] </sup>
9353 <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4024.pdf" target="_top">'N4024:
9354 Distinguishing coroutines and fibers'</a>
9355 </p></div>
9356<div class="footnote"><p><sup>[<a name="ftn.fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f1" href="#fiber.stack.protected_fixedsize.pooled_fixedsize.rationale.f1" class="para">12</a>] </sup>
9357 David R. Butenhof <span class="quote">&#8220;<span class="quote">Programming with POSIX Threads</span>&#8221;</span>
9358 </p></div>
9359</div>
9360</div>
9361<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
9362<td align="left"></td>
9363<td align="right"><div class="copyright-footer">Copyright &#169; 2013 Oliver Kowalke<p>
9364 Distributed under the Boost Software License, Version 1.0. (See accompanying
9365 file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
9366 </p>
9367</div></td>
9368</tr></table>
9369<hr>
9370<div class="spirit-nav">
9371<a accesskey="p" href="../protected_fixedsize.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../protected_fixedsize.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a>
9372</div>
9373</body>
9374</html>