support for context::fiber

This commit is contained in:
Oliver Kowalke 2018-01-18 21:21:28 +01:00
parent a28b850bcd
commit 49716a54d8
5 changed files with 247 additions and 256 deletions

View File

@ -11,7 +11,7 @@
#include <type_traits> #include <type_traits>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/context/continuation.hpp> #include <boost/context/fiber.hpp>
#include <boost/coroutine2/detail/state.hpp> #include <boost/coroutine2/detail/state.hpp>
@ -25,7 +25,7 @@ namespace detail {
template< typename T > template< typename T >
struct pull_coroutine< T >::control_block { struct pull_coroutine< T >::control_block {
boost::context::continuation c; boost::context::fiber c;
typename push_coroutine< T >::control_block * other; typename push_coroutine< T >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -37,7 +37,7 @@ struct pull_coroutine< T >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( typename push_coroutine< T >::control_block *, boost::context::continuation &) noexcept; control_block( typename push_coroutine< T >::control_block *, boost::context::fiber &) noexcept;
~control_block(); ~control_block();
@ -66,7 +66,7 @@ struct pull_coroutine< T & >::control_block {
} }
}; };
boost::context::continuation c; boost::context::fiber c;
typename push_coroutine< T & >::control_block * other; typename push_coroutine< T & >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -78,7 +78,7 @@ struct pull_coroutine< T & >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( typename push_coroutine< T & >::control_block *, boost::context::continuation &) noexcept; control_block( typename push_coroutine< T & >::control_block *, boost::context::fiber &) noexcept;
control_block( control_block &) = delete; control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete; control_block & operator=( control_block &) = delete;
@ -95,7 +95,7 @@ struct pull_coroutine< T & >::control_block {
}; };
struct pull_coroutine< void >::control_block { struct pull_coroutine< void >::control_block {
boost::context::continuation c; boost::context::fiber c;
push_coroutine< void >::control_block * other; push_coroutine< void >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -105,7 +105,7 @@ struct pull_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( push_coroutine< void >::control_block *, boost::context::continuation &) noexcept; control_block( push_coroutine< void >::control_block *, boost::context::fiber &) noexcept;
control_block( control_block &) = delete; control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete; control_block & operator=( control_block &) = delete;

View File

@ -15,7 +15,7 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/context/continuation.hpp> #include <boost/context/fiber.hpp>
#include <boost/coroutine2/detail/config.hpp> #include <boost/coroutine2/detail/config.hpp>
#include <boost/coroutine2/detail/forced_unwind.hpp> #include <boost/coroutine2/detail/forced_unwind.hpp>
@ -34,7 +34,7 @@ namespace detail {
template< typename T > template< typename T >
void void
pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept { pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -45,16 +45,9 @@ template< typename T >
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, pull_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
Fn && fn) : Fn && fn) :
c{},
other{ nullptr },
state{ state_t::unwind },
except{},
bvalid{ false },
storage{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized push_coroutine< T > // create synthesized push_coroutine< T >
typename push_coroutine< T >::control_block synthesized_cb{ this, c }; typename push_coroutine< T >::control_block synthesized_cb{ this, c };
push_coroutine< T > synthesized{ & synthesized_cb }; push_coroutine< T > synthesized{ & synthesized_cb };
@ -76,11 +69,10 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
// jump back // jump back
return other->c.resume(); return other->c.resume();
}, },
std::forward< Fn >( fn) ) ); std::forward< Fn >( fn) ) },
#else #else
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
[this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
// create synthesized push_coroutine< T > // create synthesized push_coroutine< T >
typename push_coroutine< T >::control_block synthesized_cb{ this, c }; typename push_coroutine< T >::control_block synthesized_cb{ this, c };
push_coroutine< T > synthesized{ & synthesized_cb }; push_coroutine< T > synthesized{ & synthesized_cb };
@ -101,8 +93,14 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
state |= state_t::complete; state |= state_t::complete;
// jump back // jump back
return other->c.resume(); return other->c.resume();
}); } },
#endif #endif
other{ nullptr },
state{ state_t::unwind },
except{},
bvalid{ false },
storage{} {
c = c.resume();
if ( except) { if ( except) {
std::rethrow_exception( except); std::rethrow_exception( except);
} }
@ -110,7 +108,7 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
template< typename T > template< typename T >
pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb, pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },
@ -184,7 +182,7 @@ pull_coroutine< T >::control_block::valid() const noexcept {
template< typename T > template< typename T >
void void
pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -195,16 +193,9 @@ template< typename T >
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, pull_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
Fn && fn) : Fn && fn) :
c{},
other{ nullptr },
state{ state_t::unwind },
except{},
bvalid{ false },
storage{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized push_coroutine< T & > // create synthesized push_coroutine< T & >
typename push_coroutine< T & >::control_block synthesized_cb{ this, c }; typename push_coroutine< T & >::control_block synthesized_cb{ this, c };
push_coroutine< T & > synthesized{ & synthesized_cb }; push_coroutine< T & > synthesized{ & synthesized_cb };
@ -226,11 +217,10 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
// jump back // jump back
return other->c.resume(); return other->c.resume();
}, },
std::forward< Fn >( fn) ) ); std::forward< Fn >( fn) ) },
#else #else
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
[this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
// create synthesized push_coroutine< T & > // create synthesized push_coroutine< T & >
typename push_coroutine< T & >::control_block synthesized_cb{ this, c }; typename push_coroutine< T & >::control_block synthesized_cb{ this, c };
push_coroutine< T & > synthesized{ & synthesized_cb }; push_coroutine< T & > synthesized{ & synthesized_cb };
@ -251,8 +241,14 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
state |= state_t::complete; state |= state_t::complete;
// jump back // jump back
return other->c.resume(); return other->c.resume();
}); } },
#endif #endif
other{ nullptr },
state{ state_t::unwind },
except{},
bvalid{ false },
storage{} {
c = c.resume();
if ( except) { if ( except) {
std::rethrow_exception( except); std::rethrow_exception( except);
} }
@ -260,7 +256,7 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
template< typename T > template< typename T >
pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb, pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T & >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },
@ -311,7 +307,7 @@ pull_coroutine< T & >::control_block::valid() const noexcept {
inline inline
void void
pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept { pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -321,14 +317,9 @@ pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, pull_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
Fn && fn) : Fn && fn) :
c{},
other{ nullptr },
state{ state_t::unwind },
except{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized push_coroutine< void > // create synthesized push_coroutine< void >
typename push_coroutine< void >::control_block synthesized_cb{ this, c }; typename push_coroutine< void >::control_block synthesized_cb{ this, c };
push_coroutine< void > synthesized{ & synthesized_cb }; push_coroutine< void > synthesized{ & synthesized_cb };
@ -350,11 +341,10 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
// jump back // jump back
return other->c.resume(); return other->c.resume();
}, },
std::forward< Fn >( fn) ) ); std::forward< Fn >( fn) ) },
#else #else
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), [this,fn_=std::forward< Fn >( fn)]( boost::context::fiber && c) mutable {
[this,fn_=std::forward< Fn >( fn)]( boost::context::continuation && c) mutable {
// create synthesized push_coroutine< void > // create synthesized push_coroutine< void >
typename push_coroutine< void >::control_block synthesized_cb{ this, c }; typename push_coroutine< void >::control_block synthesized_cb{ this, c };
push_coroutine< void > synthesized{ & synthesized_cb }; push_coroutine< void > synthesized{ & synthesized_cb };
@ -375,8 +365,12 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
state |= state_t::complete; state |= state_t::complete;
// jump back to ctx // jump back to ctx
return other->c.resume(); return other->c.resume();
}); } },
#endif #endif
other{ nullptr },
state{ state_t::unwind },
except{} {
c = c.resume();
if ( except) { if ( except) {
std::rethrow_exception( except); std::rethrow_exception( except);
} }
@ -384,7 +378,7 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
inline inline
pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb, pull_coroutine< void >::control_block::control_block( push_coroutine< void >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },

View File

@ -10,7 +10,7 @@
#include <exception> #include <exception>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/context/continuation.hpp> #include <boost/context/fiber.hpp>
#include <boost/coroutine2/detail/state.hpp> #include <boost/coroutine2/detail/state.hpp>
@ -24,7 +24,7 @@ namespace detail {
template< typename T > template< typename T >
struct push_coroutine< T >::control_block { struct push_coroutine< T >::control_block {
boost::context::continuation c; boost::context::fiber c;
typename pull_coroutine< T >::control_block * other; typename pull_coroutine< T >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -34,7 +34,7 @@ struct push_coroutine< T >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( typename pull_coroutine< T >::control_block *, boost::context::continuation &) noexcept; control_block( typename pull_coroutine< T >::control_block *, boost::context::fiber &) noexcept;
control_block( control_block &) = delete; control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete; control_block & operator=( control_block &) = delete;
@ -50,7 +50,7 @@ struct push_coroutine< T >::control_block {
template< typename T > template< typename T >
struct push_coroutine< T & >::control_block { struct push_coroutine< T & >::control_block {
boost::context::continuation c; boost::context::fiber c;
typename pull_coroutine< T & >::control_block * other; typename pull_coroutine< T & >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -60,7 +60,7 @@ struct push_coroutine< T & >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( typename pull_coroutine< T & >::control_block *, boost::context::continuation &) noexcept; control_block( typename pull_coroutine< T & >::control_block *, boost::context::fiber &) noexcept;
control_block( control_block &) = delete; control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete; control_block & operator=( control_block &) = delete;
@ -73,7 +73,7 @@ struct push_coroutine< T & >::control_block {
}; };
struct push_coroutine< void >::control_block { struct push_coroutine< void >::control_block {
boost::context::continuation c; boost::context::fiber c;
pull_coroutine< void >::control_block * other; pull_coroutine< void >::control_block * other;
state_t state; state_t state;
std::exception_ptr except; std::exception_ptr except;
@ -83,7 +83,7 @@ struct push_coroutine< void >::control_block {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
control_block( context::preallocated, StackAllocator &&, Fn &&); control_block( context::preallocated, StackAllocator &&, Fn &&);
control_block( pull_coroutine< void >::control_block *, boost::context::continuation &) noexcept; control_block( pull_coroutine< void >::control_block *, boost::context::fiber &) noexcept;
control_block( control_block &) = delete; control_block( control_block &) = delete;
control_block & operator=( control_block &) = delete; control_block & operator=( control_block &) = delete;

View File

@ -14,7 +14,7 @@
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/context/continuation.hpp> #include <boost/context/fiber.hpp>
#include <boost/coroutine2/detail/config.hpp> #include <boost/coroutine2/detail/config.hpp>
#include <boost/coroutine2/detail/forced_unwind.hpp> #include <boost/coroutine2/detail/forced_unwind.hpp>
@ -33,7 +33,7 @@ namespace detail {
template< typename T > template< typename T >
void void
push_coroutine< T >::control_block::destroy( control_block * cb) noexcept { push_coroutine< T >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -44,14 +44,9 @@ template< typename T >
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, push_coroutine< T >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
Fn && fn) : Fn && fn) :
c{},
other{ nullptr },
state{ state_t::unwind },
except{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< T > // create synthesized pull_coroutine< T >
typename pull_coroutine< T >::control_block synthesized_cb{ this, c }; typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
pull_coroutine< T > synthesized{ & synthesized_cb }; pull_coroutine< T > synthesized{ & synthesized_cb };
@ -74,11 +69,10 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
// jump back // jump back
return other->c.resume(); return other->c.resume();
}, },
std::forward< Fn >( fn) ) ); std::forward< Fn >( fn) ) },
#else #else
c = boost::context::callcc( c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc), [this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
[this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< T > // create synthesized pull_coroutine< T >
typename pull_coroutine< T >::control_block synthesized_cb{ this, c }; typename pull_coroutine< T >::control_block synthesized_cb{ this, c };
pull_coroutine< T > synthesized{ & synthesized_cb }; pull_coroutine< T > synthesized{ & synthesized_cb };
@ -100,13 +94,17 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
state |= state_t::complete; state |= state_t::complete;
// jump back // jump back
return other->c.resume(); return other->c.resume();
}); } },
#endif #endif
other{ nullptr },
state{ state_t::unwind },
except{} {
c = c.resume();
} }
template< typename T > template< typename T >
push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb, push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },
@ -157,7 +155,7 @@ push_coroutine< T >::control_block::valid() const noexcept {
template< typename T > template< typename T >
void void
push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -168,69 +166,68 @@ template< typename T >
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, push_coroutine< T & >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc,
Fn && fn) : Fn && fn) :
c{}, #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
// create synthesized pull_coroutine< T & >
typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
pull_coroutine< T & > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
other->c = other->c.resume();
},
std::forward< Fn >( fn) ) },
#else
c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
[this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
// create synthesized pull_coroutine< T & >
typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
pull_coroutine< T & > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
other->c = other->c.resume();
return std::move( other->c);
} },
#endif
other{ nullptr }, other{ nullptr },
state{ state_t::unwind }, state{ state_t::unwind },
except{} { except{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) c = c.resume();
c = boost::context::callcc(
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< T & >
typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
pull_coroutine< T & > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
return other->c.resume();
},
std::forward< Fn >( fn) ) );
#else
c = boost::context::callcc(
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
[this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< T & >
typename pull_coroutine< T & >::control_block synthesized_cb{ this, c };
pull_coroutine< T & > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
return other->c.resume();
});
#endif
} }
template< typename T > template< typename T >
push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb, push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T & >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },
@ -269,7 +266,7 @@ push_coroutine< T & >::control_block::valid() const noexcept {
inline inline
void void
push_coroutine< void >::control_block::destroy( control_block * cb) noexcept { push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
boost::context::continuation c = std::move( cb->c); boost::context::fiber c = std::move( cb->c);
// destroy control structure // destroy control structure
cb->~control_block(); cb->~control_block();
// destroy coroutine's stack // destroy coroutine's stack
@ -278,69 +275,69 @@ push_coroutine< void >::control_block::destroy( control_block * cb) noexcept {
template< typename StackAllocator, typename Fn > template< typename StackAllocator, typename Fn >
push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, Fn && fn) : push_coroutine< void >::control_block::control_block( context::preallocated palloc, StackAllocator && salloc, Fn && fn) :
c{}, #if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS)
c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::fiber && c) mutable {
// create synthesized pull_coroutine< void >
typename pull_coroutine< void >::control_block synthesized_cb{ this, c };
pull_coroutine< void > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
other->c = other->c.resume();
return std::move( other->c);
},
std::forward< Fn >( fn) ) },
#else
c{ std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
[this,fn_=std::forward< Fn >( fn)](boost::context::fiber && c) mutable {
// create synthesized pull_coroutine< void >
typename pull_coroutine< void >::control_block synthesized_cb{ this, c};
pull_coroutine< void > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
other->c = other->c.resume();
return std::move( other->c);
} },
#endif
other{ nullptr }, other{ nullptr },
state{ state_t::unwind }, state{ state_t::unwind },
except{} { except{} {
#if defined(BOOST_NO_CXX14_GENERIC_LAMBDAS) c = c.resume();
c = boost::context::callcc(
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
wrap( [this](typename std::decay< Fn >::type & fn_,boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< void >
typename pull_coroutine< void >::control_block synthesized_cb{ this, c };
pull_coroutine< void > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
return other->c.resume();
},
std::forward< Fn >( fn) ) );
#else
c = boost::context::callcc(
std::allocator_arg, palloc, std::forward< StackAllocator >( salloc),
[this,fn_=std::forward< Fn >( fn)](boost::context::continuation && c) mutable {
// create synthesized pull_coroutine< void >
typename pull_coroutine< void >::control_block synthesized_cb{ this, c};
pull_coroutine< void > synthesized{ & synthesized_cb };
other = & synthesized_cb;
other->c = other->c.resume();
if ( state_t::none == ( state & state_t::destroy) ) {
try {
auto fn = std::move( fn_);
// call coroutine-fn with synthesized pull_coroutine as argument
fn( synthesized);
} catch ( boost::context::detail::forced_unwind const&) {
throw;
} catch (...) {
// store other exceptions in exception-pointer
except = std::current_exception();
}
}
// set termination flags
state |= state_t::complete;
// jump back
return other->c.resume();
});
#endif
} }
inline inline
push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb, push_coroutine< void >::control_block::control_block( pull_coroutine< void >::control_block * cb,
boost::context::continuation & c_) noexcept : boost::context::fiber & c_) noexcept :
c{ std::move( c_) }, c{ std::move( c_) },
other{ cb }, other{ cb },
state{ state_t::none }, state{ state_t::none },

View File

@ -11,7 +11,7 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#include <boost/context/detail/invoke.hpp> #include <boost/context/detail/invoke.hpp>
#include <boost/context/continuation.hpp> #include <boost/context/fiber.hpp>
#include <boost/coroutine2/detail/config.hpp> #include <boost/coroutine2/detail/config.hpp>
@ -41,12 +41,12 @@ public:
wrapper( wrapper && other) = default; wrapper( wrapper && other) = default;
wrapper & operator=( wrapper && other) = default; wrapper & operator=( wrapper && other) = default;
boost::context::continuation boost::context::fiber
operator()( boost::context::continuation && c) { operator()( boost::context::fiber && c) {
return boost::context::detail::invoke( return boost::context::detail::invoke(
std::move( fn1_), std::move( fn1_),
fn2_, fn2_,
std::forward< boost::context::continuation >( c) ); std::forward< boost::context::fiber >( c) );
} }
}; };