]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/coroutine2/detail/push_control_block_cc.ipp
Add patch for failing prerm scripts
[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>
16
11fdf7f2 17#include <boost/context/fiber.hpp>
b32b8144
FG
18
19#include <boost/coroutine2/detail/config.hpp>
20#include <boost/coroutine2/detail/forced_unwind.hpp>
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;
62 } catch (...) {
63 // store other exceptions in exception-pointer
64 except = std::current_exception();
65 }
66 }
67 // set termination flags
68 state |= state_t::complete;
69 // jump back
11fdf7f2
TL
70 other->c = std::move( other->c).resume();
71 return std::move( other->c);
72 },
73 std::forward< Fn >( fn) ) },
74#else
75 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
76 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
77 // create synthesized pull_coroutine< T >
78 typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
79 pull_coroutine< T > synthesized{ & synthesized_cb };
80 other = & synthesized_cb;
81 other->c = std::move( other->c).resume();
82 if ( state_t::none == ( state & state_t::destroy) ) {
83 try {
84 auto fn = std::move( fn_);
85 // call coroutine-fn with synthesized pull_coroutine as argument
86 fn( synthesized);
87 } catch ( boost::context::detail::forced_unwind const&) {
88 throw;
89 } catch (...) {
90 // store other exceptions in exception-pointer
91 except = std::current_exception();
92 }
93 }
94 // set termination flags
95 state |= state_t::complete;
96 // jump back
97 return std::move( other->c).resume();
98 } },
b32b8144 99#endif
11fdf7f2
TL
100 other{ nullptr },
101 state{ state_t::unwind },
102 except{} {
103 c = std::move( c).resume();
b32b8144
FG
104}
105
106template< typename T >
107push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
11fdf7f2 108 boost::context::fiber & c_) noexcept :
b32b8144
FG
109 c{ std::move( c_) },
110 other{ cb },
111 state{ state_t::none },
112 except{} {
113}
114
115template< typename T >
116void
117push_coroutine< T >::control_block::deallocate() noexcept {
118 if ( state_t::none != ( state & state_t::unwind) ) {
119 destroy( this);
120 }
121}
122
123template< typename T >
124void
125push_coroutine< T >::control_block::resume( T const& data) {
126 // pass data to other context
127 other->set( data);
128 // resume other context
11fdf7f2 129 c = std::move( c).resume();
b32b8144
FG
130 if ( except) {
131 std::rethrow_exception( except);
132 }
133}
134
135template< typename T >
136void
137push_coroutine< T >::control_block::resume( T && data) {
138 // pass data to other context
139 other->set( std::move( data) );
140 // resume other context
11fdf7f2 141 c = std::move( c).resume();
b32b8144
FG
142 if ( except) {
143 std::rethrow_exception( except);
144 }
145}
146
147template< typename T >
148bool
149push_coroutine< T >::control_block::valid() const noexcept {
150 return state_t::none == ( state & state_t::complete );
151}
152
153
154// push_coroutine< T & >
155
156template< typename T >
157void
158push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
11fdf7f2 159 boost::context::fiber c = std::move( cb->c);
b32b8144
FG
160 // destroy control structure
161 cb->~control_block();
162 // destroy coroutine's stack
163 cb->state |= state_t::destroy;
164}
165
166template< typename T >
167template< typename StackAllocator, typename Fn >
168push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
169 Fn && fn) :
b32b8144 170#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
11fdf7f2
TL
171 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
172 wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
b32b8144
FG
173 // create synthesized pull_coroutine< T & >
174 typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
175 pull_coroutine< T & > synthesized{ & synthesized_cb };
176 other = & synthesized_cb;
11fdf7f2 177 other->c = std::move( other->c).resume();
b32b8144
FG
178 if ( state_t::none == ( state & state_t::destroy) ) {
179 try {
180 auto fn = std::move( fn_);
181 // call coroutine-fn with synthesized pull_coroutine as argument
182 fn( synthesized);
183 } catch ( boost::context::detail::forced_unwind const&) {
184 throw;
185 } catch (...) {
186 // store other exceptions in exception-pointer
187 except = std::current_exception();
188 }
189 }
190 // set termination flags
191 state |= state_t::complete;
192 // jump back
11fdf7f2
TL
193 other->c = std::move( other->c).resume();
194 return std::move( other->c);
195 },
196 std::forward< Fn >( fn) ) },
197#else
198 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
199 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
200 // create synthesized pull_coroutine< T & >
201 typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
202 pull_coroutine< T & > synthesized{ & synthesized_cb };
203 other = & synthesized_cb;
204 other->c = std::move( other->c).resume();
205 if ( state_t::none == ( state & state_t::destroy) ) {
206 try {
207 auto fn = std::move( fn_);
208 // call coroutine-fn with synthesized pull_coroutine as argument
209 fn( synthesized);
210 } catch ( boost::context::detail::forced_unwind const&) {
211 throw;
212 } catch (...) {
213 // store other exceptions in exception-pointer
214 except = std::current_exception();
215 }
216 }
217 // set termination flags
218 state |= state_t::complete;
219 // jump back
220 other->c = std::move( other->c).resume();
221 return std::move( other->c);
222 } },
b32b8144 223#endif
11fdf7f2
TL
224 other{ nullptr },
225 state{ state_t::unwind },
226 except{} {
227 c = std::move( c).resume();
b32b8144
FG
228}
229
230template< typename T >
231push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
11fdf7f2 232 boost::context::fiber & c_) noexcept :
b32b8144
FG
233 c{ std::move( c_) },
234 other{ cb },
235 state{ state_t::none },
236 except{} {
237}
238
239template< typename T >
240void
241push_coroutine< T & >::control_block::deallocate() noexcept {
242 if ( state_t::none != ( state & state_t::unwind) ) {
243 destroy( this);
244 }
245}
246
247template< typename T >
248void
249push_coroutine< T & >::control_block::resume( T & data) {
250 // pass data to other context
251 other->set( data);
252 // resume other context
11fdf7f2 253 c = std::move( c).resume();
b32b8144
FG
254 if ( except) {
255 std::rethrow_exception( except);
256 }
257}
258
259template< typename T >
260bool
261push_coroutine< T & >::control_block::valid() const noexcept {
262 return state_t::none == ( state & state_t::complete );
263}
264
265
266// push_coroutine< void >
267
268inline
269void
270push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
11fdf7f2 271 boost::context::fiber c = std::move( cb->c);
b32b8144
FG
272 // destroy control structure
273 cb->~control_block();
274 // destroy coroutine's stack
275 cb->state |= state_t::destroy;
276}
277
278template< typename StackAllocator, typename Fn >
279push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, Fn && fn) :
b32b8144 280#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
11fdf7f2
TL
281 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
282 wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
b32b8144 283 // create synthesized pull_coroutine< void >
11fdf7f2 284 typename pull_coroutine< void >::control_block synthesized_cb{ this, c };
b32b8144
FG
285 pull_coroutine< void > synthesized{ & synthesized_cb };
286 other = & synthesized_cb;
11fdf7f2 287 other->c = std::move( other->c).resume();
b32b8144
FG
288 if ( state_t::none == ( state & state_t::destroy) ) {
289 try {
290 auto fn = std::move( fn_);
291 // call coroutine-fn with synthesized pull_coroutine as argument
292 fn( synthesized);
293 } catch ( boost::context::detail::forced_unwind const&) {
294 throw;
295 } catch (...) {
296 // store other exceptions in exception-pointer
297 except = std::current_exception();
298 }
299 }
300 // set termination flags
301 state |= state_t::complete;
302 // jump back
11fdf7f2
TL
303 other->c = std::move( other->c).resume();
304 return std::move( other->c);
305 },
306 std::forward< Fn >( fn) ) },
307#else
308 c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
309 [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
310 // create synthesized pull_coroutine< void >
311 typename pull_coroutine< void >::control_block synthesized_cb{ this, c};
312 pull_coroutine< void > synthesized{ & synthesized_cb };
313 other = & synthesized_cb;
314 other->c = std::move( other->c).resume();
315 if ( state_t::none == ( state & state_t::destroy) ) {
316 try {
317 auto fn = std::move( fn_);
318 // call coroutine-fn with synthesized pull_coroutine as argument
319 fn( synthesized);
320 } catch ( boost::context::detail::forced_unwind const&) {
321 throw;
322 } catch (...) {
323 // store other exceptions in exception-pointer
324 except = std::current_exception();
325 }
326 }
327 // set termination flags
328 state |= state_t::complete;
329 // jump back
330 other->c = std::move( other->c).resume();
331 return std::move( other->c);
332 } },
b32b8144 333#endif
11fdf7f2
TL
334 other{ nullptr },
335 state{ state_t::unwind },
336 except{} {
337 c = std::move( c).resume();
b32b8144
FG
338}
339
340inline
341push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
11fdf7f2 342 boost::context::fiber & c_) noexcept :
b32b8144
FG
343 c{ std::move( c_) },
344 other{ cb },
345 state{ state_t::none },
346 except{} {
347}
348
349inline
350void
351push_coroutine< void >::control_block::deallocate() noexcept {
352 if ( state_t::none != ( state & state_t::unwind) ) {
353 destroy( this);
354 }
355}
356
357inline
358void
359push_coroutine< void >::control_block::resume() {
11fdf7f2 360 c = std::move( c).resume();
b32b8144
FG
361 if ( except) {
362 std::rethrow_exception( except);
363 }
364}
365
366inline
367bool
368push_coroutine< void >::control_block::valid() const noexcept {
369 return state_t::none == ( state & state_t::complete );
370}
371
372}}}
373
374#ifdef BOOST_HAS_ABI_HEADERS
375# include BOOST_ABI_SUFFIX
376#endif
377
378#endif // BOOST_COROUTINES2_DETAIL_PUSH_CONTROL_BLOCK_IPP