]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/coroutine2/detail/push_control_block_cc.ipp
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / boost / boost / coroutine2 / detail / push_control_block_cc.ipp
CommitLineData
b32b8144
FG
1
2// Copyright Oliver Kowalke 2014.
3// Distributed under the Boost Software License, Version 1.0.
4// (See accompanying file LICENSE_1_0.txt or copy at
5// http://www.boost.org/LICENSE_1_0.txt)
6
7#ifndef BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
8#define BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP
9
10#include <algorithm>
11#include <exception>
12#include <memory>
13
14#include <boost/assert.hpp>
15#include <boost/config.hpp>
92f5a8d4 16#include <boost/context/detail/config.hpp>
b32b8144 17
11fdf7f2 18#include <boost/context/fiber.hpp>
b32b8144
FG
19
20#include <boost/coroutine2/detail/config.hpp>
b32b8144
FG
21#include <boost/coroutine2/detail/wrap.hpp>
22
23#ifdef BOOST_HAS_ABI_HEADERS
24# include BOOST_ABI_PREFIX
25#endif
26
27namespace boost {
28namespace coroutines2 {
29namespace detail {
30
31// push_coroutine< T >
32
33template< typename T >
34void
35push_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
11fdf7f2 36 boost::context::fiber c = std::move( cb->c);
b32b8144
FG
37 // destroy control structure
38 cb->~control_block();
39 // destroy coroutine's stack
40 cb->state |= state_t::destroy;
41}
42
43template< typename T >
44template< typename StackAllocator, typename Fn >
45push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
46 Fn && fn) :
b32b8144 47#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
11fdf7f2
TL
48 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
49 wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
b32b8144
FG
50 // create synthesized pull_coroutine< T >
51 typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
52 pull_coroutine< T > synthesized{ & synthesized_cb };
53 other = & synthesized_cb;
11fdf7f2 54 other->c = std::move( other->c).resume();
b32b8144
FG
55 if ( state_t::none == ( state & state_t::destroy) ) {
56 try {
57 auto fn = std::move( fn_);
58 // call coroutine-fn with synthesized pull_coroutine as argument
59 fn( synthesized);
60 } catch ( boost::context::detail::forced_unwind const&) {
61 throw;
92f5a8d4
TL
62#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
63 } catch ( abi::__forced_unwind const&) {
64 throw;
65#endif
b32b8144
FG
66 } catch (...) {
67 // store other exceptions in exception-pointer
68 except = std::current_exception();
69 }
70 }
71 // set termination flags
72 state |= state_t::complete;
73 // jump back
11fdf7f2
TL
74 other->c = std::move( other->c).resume();
75 return std::move( other->c);
76 },
77 std::forward< Fn >( fn) ) },
78#else
79 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
80 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
81 // create synthesized pull_coroutine< T >
82 typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
83 pull_coroutine< T > synthesized{ & synthesized_cb };
84 other = & synthesized_cb;
85 other->c = std::move( other->c).resume();
86 if ( state_t::none == ( state & state_t::destroy) ) {
87 try {
88 auto fn = std::move( fn_);
89 // call coroutine-fn with synthesized pull_coroutine as argument
90 fn( synthesized);
91 } catch ( boost::context::detail::forced_unwind const&) {
92 throw;
92f5a8d4
TL
93#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
94 } catch ( abi::__forced_unwind const&) {
95 throw;
96#endif
11fdf7f2
TL
97 } catch (...) {
98 // store other exceptions in exception-pointer
99 except = std::current_exception();
100 }
101 }
102 // set termination flags
103 state |= state_t::complete;
104 // jump back
105 return std::move( other->c).resume();
106 } },
b32b8144 107#endif
11fdf7f2
TL
108 other{ nullptr },
109 state{ state_t::unwind },
110 except{} {
111 c = std::move( c).resume();
b32b8144
FG
112}
113
114template< typename T >
115push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
11fdf7f2 116 boost::context::fiber & c_) noexcept :
b32b8144
FG
117 c{ std::move( c_) },
118 other{ cb },
119 state{ state_t::none },
120 except{} {
121}
122
123template< typename T >
124void
125push_coroutine< T >::control_block::deallocate() noexcept {
126 if ( state_t::none != ( state & state_t::unwind) ) {
127 destroy( this);
128 }
129}
130
131template< typename T >
132void
133push_coroutine< T >::control_block::resume( T const& data) {
134 // pass data to other context
135 other->set( data);
136 // resume other context
11fdf7f2 137 c = std::move( c).resume();
b32b8144
FG
138 if ( except) {
139 std::rethrow_exception( except);
140 }
141}
142
143template< typename T >
144void
145push_coroutine< T >::control_block::resume( T && data) {
146 // pass data to other context
147 other->set( std::move( data) );
148 // resume other context
11fdf7f2 149 c = std::move( c).resume();
b32b8144
FG
150 if ( except) {
151 std::rethrow_exception( except);
152 }
153}
154
155template< typename T >
156bool
157push_coroutine< T >::control_block::valid() const noexcept {
158 return state_t::none == ( state & state_t::complete );
159}
160
161
162// push_coroutine< T & >
163
164template< typename T >
165void
166push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
11fdf7f2 167 boost::context::fiber c = std::move( cb->c);
b32b8144
FG
168 // destroy control structure
169 cb->~control_block();
170 // destroy coroutine's stack
171 cb->state |= state_t::destroy;
172}
173
174template< typename T >
175template< typename StackAllocator, typename Fn >
176push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
177 Fn && fn) :
b32b8144 178#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
11fdf7f2
TL
179 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
180 wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
b32b8144
FG
181 // create synthesized pull_coroutine< T & >
182 typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
183 pull_coroutine< T & > synthesized{ & synthesized_cb };
184 other = & synthesized_cb;
11fdf7f2 185 other->c = std::move( other->c).resume();
b32b8144
FG
186 if ( state_t::none == ( state & state_t::destroy) ) {
187 try {
188 auto fn = std::move( fn_);
189 // call coroutine-fn with synthesized pull_coroutine as argument
190 fn( synthesized);
191 } catch ( boost::context::detail::forced_unwind const&) {
192 throw;
92f5a8d4
TL
193#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
194 } catch ( abi::__forced_unwind const&) {
195 throw;
196#endif
b32b8144
FG
197 } catch (...) {
198 // store other exceptions in exception-pointer
199 except = std::current_exception();
200 }
201 }
202 // set termination flags
203 state |= state_t::complete;
204 // jump back
11fdf7f2
TL
205 other->c = std::move( other->c).resume();
206 return std::move( other->c);
207 },
208 std::forward< Fn >( fn) ) },
209#else
210 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
211 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
212 // create synthesized pull_coroutine< T & >
213 typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
214 pull_coroutine< T & > synthesized{ & synthesized_cb };
215 other = & synthesized_cb;
216 other->c = std::move( other->c).resume();
217 if ( state_t::none == ( state & state_t::destroy) ) {
218 try {
219 auto fn = std::move( fn_);
220 // call coroutine-fn with synthesized pull_coroutine as argument
221 fn( synthesized);
222 } catch ( boost::context::detail::forced_unwind const&) {
223 throw;
92f5a8d4
TL
224#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
225 } catch ( abi::__forced_unwind const&) {
226 throw;
227#endif
11fdf7f2
TL
228 } catch (...) {
229 // store other exceptions in exception-pointer
230 except = std::current_exception();
231 }
232 }
233 // set termination flags
234 state |= state_t::complete;
235 // jump back
236 other->c = std::move( other->c).resume();
237 return std::move( other->c);
238 } },
b32b8144 239#endif
11fdf7f2
TL
240 other{ nullptr },
241 state{ state_t::unwind },
242 except{} {
243 c = std::move( c).resume();
b32b8144
FG
244}
245
246template< typename T >
247push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
11fdf7f2 248 boost::context::fiber & c_) noexcept :
b32b8144
FG
249 c{ std::move( c_) },
250 other{ cb },
251 state{ state_t::none },
252 except{} {
253}
254
255template< typename T >
256void
257push_coroutine< T & >::control_block::deallocate() noexcept {
258 if ( state_t::none != ( state & state_t::unwind) ) {
259 destroy( this);
260 }
261}
262
263template< typename T >
264void
265push_coroutine< T & >::control_block::resume( T & data) {
266 // pass data to other context
267 other->set( data);
268 // resume other context
11fdf7f2 269 c = std::move( c).resume();
b32b8144
FG
270 if ( except) {
271 std::rethrow_exception( except);
272 }
273}
274
275template< typename T >
276bool
277push_coroutine< T & >::control_block::valid() const noexcept {
278 return state_t::none == ( state & state_t::complete );
279}
280
281
282// push_coroutine< void >
283
284inline
285void
286push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
11fdf7f2 287 boost::context::fiber c = std::move( cb->c);
b32b8144
FG
288 // destroy control structure
289 cb->~control_block();
290 // destroy coroutine's stack
291 cb->state |= state_t::destroy;
292}
293
294template< typename StackAllocator, typename Fn >
295push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, Fn && fn) :
b32b8144 296#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
11fdf7f2
TL
297 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
298 wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
b32b8144 299 // create synthesized pull_coroutine< void >
11fdf7f2 300 typename pull_coroutine< void >::control_block synthesized_cb{ this, c };
b32b8144
FG
301 pull_coroutine< void > synthesized{ & synthesized_cb };
302 other = & synthesized_cb;
11fdf7f2 303 other->c = std::move( other->c).resume();
b32b8144
FG
304 if ( state_t::none == ( state & state_t::destroy) ) {
305 try {
306 auto fn = std::move( fn_);
307 // call coroutine-fn with synthesized pull_coroutine as argument
308 fn( synthesized);
309 } catch ( boost::context::detail::forced_unwind const&) {
310 throw;
92f5a8d4
TL
311#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
312 } catch ( abi::__forced_unwind const&) {
313 throw;
314#endif
b32b8144
FG
315 } catch (...) {
316 // store other exceptions in exception-pointer
317 except = std::current_exception();
318 }
319 }
320 // set termination flags
321 state |= state_t::complete;
322 // jump back
11fdf7f2
TL
323 other->c = std::move( other->c).resume();
324 return std::move( other->c);
325 },
326 std::forward< Fn >( fn) ) },
327#else
328 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
329 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
330 // create synthesized pull_coroutine< void >
331 typename pull_coroutine< void >::control_block synthesized_cb{ this, c};
332 pull_coroutine< void > synthesized{ & synthesized_cb };
333 other = & synthesized_cb;
334 other->c = std::move( other->c).resume();
335 if ( state_t::none == ( state & state_t::destroy) ) {
336 try {
337 auto fn = std::move( fn_);
338 // call coroutine-fn with synthesized pull_coroutine as argument
339 fn( synthesized);
340 } catch ( boost::context::detail::forced_unwind const&) {
341 throw;
92f5a8d4
TL
342#if defined( BOOST_CONTEXT_HAS_CXXABI_H )
343 } catch ( abi::__forced_unwind const&) {
344 throw;
345#endif
11fdf7f2
TL
346 } catch (...) {
347 // store other exceptions in exception-pointer
348 except = std::current_exception();
349 }
350 }
351 // set termination flags
352 state |= state_t::complete;
353 // jump back
354 other->c = std::move( other->c).resume();
355 return std::move( other->c);
356 } },
b32b8144 357#endif
11fdf7f2
TL
358 other{ nullptr },
359 state{ state_t::unwind },
360 except{} {
361 c = std::move( c).resume();
b32b8144
FG
362}
363
364inline
365push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
11fdf7f2 366 boost::context::fiber & c_) noexcept :
b32b8144
FG
367 c{ std::move( c_) },
368 other{ cb },
369 state{ state_t::none },
370 except{} {
371}
372
373inline
374void
375push_coroutine< void >::control_block::deallocate() noexcept {
376 if ( state_t::none != ( state & state_t::unwind) ) {
377 destroy( this);
378 }
379}
380
381inline
382void
383push_coroutine< void >::control_block::resume() {
11fdf7f2 384 c = std::move( c).resume();
b32b8144
FG
385 if ( except) {
386 std::rethrow_exception( except);
387 }
388}
389
390inline
391bool
392push_coroutine< void >::control_block::valid() const noexcept {
393 return state_t::none == ( state & state_t::complete );
394}
395
396}}}
397
398#ifdef BOOST_HAS_ABI_HEADERS
399# include BOOST_ABI_SUFFIX
400#endif
401
402#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP