diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:41:18 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:43:11 +0900 |
commit | f763a99a501650eff2c60288aa6f10ef916d769e (patch) | |
tree | 02af7e13f9a38c888ebf340fe764cbe7dae99da9 /boost/coroutine2 | |
parent | 5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff) | |
download | boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.gz boost-f763a99a501650eff2c60288aa6f10ef916d769e.tar.bz2 boost-f763a99a501650eff2c60288aa6f10ef916d769e.zip |
Imported Upstream version 1.62.0upstream/1.62.0
Change-Id: I9d4c1ddb7b7d8f0069217ecc582700f9fda6dd4c
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/coroutine2')
-rw-r--r-- | boost/coroutine2/detail/pull_control_block_ecv1.ipp | 126 | ||||
-rw-r--r-- | boost/coroutine2/detail/pull_control_block_ecv2.ipp | 133 | ||||
-rw-r--r-- | boost/coroutine2/detail/push_control_block_ecv1.ipp | 166 | ||||
-rw-r--r-- | boost/coroutine2/detail/push_control_block_ecv2.ipp | 123 | ||||
-rw-r--r-- | boost/coroutine2/detail/state.hpp | 3 |
5 files changed, 307 insertions, 244 deletions
diff --git a/boost/coroutine2/detail/pull_control_block_ecv1.ipp b/boost/coroutine2/detail/pull_control_block_ecv1.ipp index f271e795df..eb2ae2778f 100644 --- a/boost/coroutine2/detail/pull_control_block_ecv1.ipp +++ b/boost/coroutine2/detail/pull_control_block_ecv1.ipp @@ -36,6 +36,7 @@ void pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -52,15 +53,17 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, typename push_coroutine< T >::control_block synthesized_cb{ this, ctx }; push_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -78,15 +81,17 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, typename push_coroutine< T >::control_block synthesized_cb{ this, ctx }; push_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -120,6 +125,7 @@ pull_coroutine< T >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } // destroy data if it set @@ -181,6 +187,7 @@ void pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -197,15 +204,17 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx }; push_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -223,15 +232,17 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx }; push_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -263,6 +274,7 @@ pull_coroutine< T & >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } } @@ -305,6 +317,7 @@ void pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -320,15 +333,17 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall typename push_coroutine< void >::control_block synthesized_cb{ this, ctx }; push_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -346,15 +361,17 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall typename push_coroutine< void >::control_block synthesized_cb{ this, ctx }; push_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -384,6 +401,7 @@ pull_coroutine< void >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } } diff --git a/boost/coroutine2/detail/pull_control_block_ecv2.ipp b/boost/coroutine2/detail/pull_control_block_ecv2.ipp index 785bc59ff1..766a3f59c7 100644 --- a/boost/coroutine2/detail/pull_control_block_ecv2.ipp +++ b/boost/coroutine2/detail/pull_control_block_ecv2.ipp @@ -37,6 +37,7 @@ pull_coroutine< T >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx( nullptr); } @@ -53,15 +54,17 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, typename push_coroutine< T >::control_block synthesized_cb{ this, ctx }; push_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -80,15 +83,17 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, typename push_coroutine< T >::control_block synthesized_cb{ this, ctx }; push_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -104,9 +109,7 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc, bvalid{ false }, storage{} { // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns - auto result = ctx( nullptr); - ctx = std::move( std::get< 0 >( result) ); - set( std::get< 1 >( result) ); + resume(); } template< typename T > @@ -184,6 +187,7 @@ pull_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx( nullptr); } @@ -200,15 +204,17 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx }; push_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -227,15 +233,17 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo typename push_coroutine< T & >::control_block synthesized_cb{ this, ctx }; push_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -250,9 +258,7 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo except{}, t{ nullptr } { // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns - auto result = ctx( nullptr); - ctx = std::move( std::get< 0 >( result) ); - t = std::get< 1 >( result); + resume(); } template< typename T > @@ -306,6 +312,7 @@ pull_coroutine< void >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx(); } @@ -321,15 +328,17 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall typename push_coroutine< void >::control_block synthesized_cb{ this, ctx }; push_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -346,15 +355,17 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall typename push_coroutine< void >::control_block synthesized_cb{ this, ctx }; push_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - auto fn = std::move( fn_); - // call coroutine-fn with synthesized push_coroutine as argument - fn( synthesized); - } catch ( boost::context::detail::forced_unwind const&) { - throw; - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + auto fn = std::move( fn_); + // call coroutine-fn with synthesized push_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; @@ -367,7 +378,7 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall state{ state_t::unwind }, except{} { // enter coroutine-fn in order to have first value available after ctor (of `*this`) returns - ctx = ctx(); + resume(); } inline diff --git a/boost/coroutine2/detail/push_control_block_ecv1.ipp b/boost/coroutine2/detail/push_control_block_ecv1.ipp index f9119fd771..cc9622dfbe 100644 --- a/boost/coroutine2/detail/push_control_block_ecv1.ipp +++ b/boost/coroutine2/detail/push_control_block_ecv1.ipp @@ -37,6 +37,7 @@ void push_coroutine< T >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -53,19 +54,21 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc, typename pull_coroutine< T >::control_block synthesized_cb{ this, ctx }; pull_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - T * t = static_cast< T * >( ctx() ); - // set transferred value - synthesized_cb.set( t); - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + T * t = static_cast< T * >( ctx() ); + // set transferred value + synthesized_cb.set( t); + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -83,19 +86,21 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc, typename pull_coroutine< T >::control_block synthesized_cb{ this, ctx }; pull_coroutine< T > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - T * t = static_cast< T * >( ctx() ); - // set transferred value - synthesized_cb.set( t); - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + T * t = static_cast< T * >( ctx() ); + // set transferred value + synthesized_cb.set( t); + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -125,6 +130,7 @@ push_coroutine< T >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } } @@ -173,6 +179,7 @@ void push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -189,19 +196,21 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo typename pull_coroutine< T & >::control_block synthesized_cb{ this, ctx }; pull_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - T * t = static_cast< T * >( ctx() ); - // set transferred value - synthesized_cb.t = t; - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + T * t = static_cast< T * >( ctx() ); + // set transferred value + synthesized_cb.t = t; + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -219,19 +228,21 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo typename pull_coroutine< T & >::control_block synthesized_cb{ this, ctx }; pull_coroutine< T & > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - T * t = static_cast< T * >( ctx() ); - // set transferred value - synthesized_cb.t = t; - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + T * t = static_cast< T * >( ctx() ); + // set transferred value + synthesized_cb.t = t; + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -261,6 +272,7 @@ push_coroutine< T & >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } } @@ -298,6 +310,7 @@ void push_coroutine< void >::control_block::destroy( control_block * cb) noexcept { boost::context::execution_context ctx = cb->ctx; // destroy control structure + cb->state |= state_t::destroy; cb->~control_block(); } @@ -313,17 +326,19 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx }; pull_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - ctx(); - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + ctx(); + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -341,17 +356,19 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx }; pull_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - try { - // jump back to ctor - ctx(); - auto fn = std::move( fn_); - // call coroutine-fn with synthesized pull_coroutine as argument - fn( synthesized); - } catch ( forced_unwind const&) { - // do nothing for unwinding exception - } catch (...) { - // store other exceptions in exception-pointer - except = std::current_exception(); + if ( state_t::none == ( state & state_t::destroy) ) { + try { + // jump back to ctor + ctx(); + auto fn = std::move( fn_); + // call coroutine-fn with synthesized pull_coroutine as argument + fn( synthesized); + } catch ( forced_unwind const&) { + // do nothing for unwinding exception + } catch (...) { + // store other exceptions in exception-pointer + except = std::current_exception(); + } } // set termination flags state |= state_t::complete; @@ -381,6 +398,7 @@ push_coroutine< void >::control_block::~control_block() { if ( state_t::none == ( state & state_t::complete) && state_t::none != ( state & state_t::unwind) ) { // unwind coroutine stack + other->ctx = boost::context::execution_context::current(); ctx( context::exec_ontop_arg, unwind_coroutine); } } diff --git a/boost/coroutine2/detail/push_control_block_ecv2.ipp b/boost/coroutine2/detail/push_control_block_ecv2.ipp index bfdee06a18..f940bb13b7 100644 --- a/boost/coroutine2/detail/push_control_block_ecv2.ipp +++ b/boost/coroutine2/detail/push_control_block_ecv2.ipp @@ -36,6 +36,7 @@ push_coroutine< T >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx( nullptr); } @@ -54,15 +55,17 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc, other = & synthesized_cb; // set transferred value synthesized_cb.set( data); - 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(); + 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; @@ -83,15 +86,17 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc, other = & synthesized_cb; // set transferred value synthesized_cb.set( data); - 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(); + 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; @@ -161,6 +166,7 @@ push_coroutine< T & >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx( nullptr); } @@ -179,15 +185,17 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo other = & synthesized_cb; // set transferred value synthesized_cb.t = data; - 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(); + 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; @@ -208,15 +216,17 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo other = & synthesized_cb; // set transferred value synthesized_cb.t = data; - 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(); + 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; @@ -275,6 +285,7 @@ push_coroutine< void >::control_block::destroy( control_block * cb) noexcept { // destroy control structure cb->~control_block(); // destroy coroutine's stack + cb->state |= state_t::destroy; ctx(); } @@ -289,15 +300,17 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx }; pull_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - 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(); + 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; @@ -314,15 +327,17 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall typename pull_coroutine< void >::control_block synthesized_cb{ this, ctx}; pull_coroutine< void > synthesized{ & synthesized_cb }; other = & synthesized_cb; - 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(); + 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; diff --git a/boost/coroutine2/detail/state.hpp b/boost/coroutine2/detail/state.hpp index e338a5aed4..2541fb4ede 100644 --- a/boost/coroutine2/detail/state.hpp +++ b/boost/coroutine2/detail/state.hpp @@ -25,7 +25,8 @@ namespace detail { enum class state_t : unsigned int { none = 0, complete = 1 << 1, - unwind = 1 << 2 + unwind = 1 << 2, + destroy = 1 << 3 }; |