summaryrefslogtreecommitdiff
path: root/boost/coroutine2
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:41:18 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:43:11 +0900
commitf763a99a501650eff2c60288aa6f10ef916d769e (patch)
tree02af7e13f9a38c888ebf340fe764cbe7dae99da9 /boost/coroutine2
parent5cde13f21d36c7224b0e13d11c4b49379ae5210d (diff)
downloadboost-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.ipp126
-rw-r--r--boost/coroutine2/detail/pull_control_block_ecv2.ipp133
-rw-r--r--boost/coroutine2/detail/push_control_block_ecv1.ipp166
-rw-r--r--boost/coroutine2/detail/push_control_block_ecv2.ipp123
-rw-r--r--boost/coroutine2/detail/state.hpp3
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
};