mirror of
https://github.com/boostorg/coroutine2.git
synced 2025-05-11 13:34:08 +00:00
execution_context does not track parents + no exceptions catched
- execution_context does not track parent - execution_context calls std::terminate() if execption is thrown - coroutine has to catch exception and store it in exception_ptr to rethrow it
This commit is contained in:
parent
2d5d7e4792
commit
bdc7cb82e5
@ -27,6 +27,7 @@ struct pull_coroutine< T >::control_block {
|
|||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
||||||
@ -50,6 +51,7 @@ struct pull_coroutine< T & >::control_block {
|
|||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
||||||
@ -67,11 +69,12 @@ struct pull_coroutine< T & >::control_block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct pull_coroutine< void >::control_block {
|
struct pull_coroutine< void >::control_block {
|
||||||
push_coroutine< void >::control_block * other;
|
push_coroutine< void >::control_block * other;
|
||||||
boost::context::execution_context caller;
|
boost::context::execution_context caller;
|
||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
||||||
|
@ -45,6 +45,9 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -53,7 +56,8 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ) {
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +67,8 @@ pull_coroutine< T >::control_block::control_block( typename push_coroutine< T >:
|
|||||||
caller( other->callee),
|
caller( other->callee),
|
||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0) {
|
state( 0),
|
||||||
|
except() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
@ -80,6 +85,9 @@ template< typename T >
|
|||||||
void
|
void
|
||||||
pull_coroutine< T >::control_block::resume() {
|
pull_coroutine< T >::control_block::resume() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
@ -112,6 +120,9 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -120,7 +131,8 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ) {
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +142,8 @@ pull_coroutine< T & >::control_block::control_block( typename push_coroutine< T
|
|||||||
caller( other->callee),
|
caller( other->callee),
|
||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0) {
|
state( 0),
|
||||||
|
except() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
@ -147,6 +160,9 @@ template< typename T >
|
|||||||
void
|
void
|
||||||
pull_coroutine< T & >::control_block::resume() {
|
pull_coroutine< T & >::control_block::resume() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
@ -178,6 +194,9 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -186,7 +205,8 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
BOOST_ASSERT_MSG( false, "pull_coroutine is complete");
|
||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ) {
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +216,8 @@ pull_coroutine< void >::control_block::control_block( push_coroutine< void >::co
|
|||||||
caller( other->callee),
|
caller( other->callee),
|
||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0) {
|
state( 0),
|
||||||
|
except() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -213,6 +234,9 @@ inline
|
|||||||
void
|
void
|
||||||
pull_coroutine< void >::control_block::resume() {
|
pull_coroutine< void >::control_block::resume() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
|
@ -27,6 +27,7 @@ struct push_coroutine< T >::control_block {
|
|||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
T * t;
|
T * t;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
@ -53,6 +54,7 @@ struct push_coroutine< T & >::control_block {
|
|||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
T * t;
|
T * t;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
@ -71,11 +73,12 @@ struct push_coroutine< T & >::control_block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct push_coroutine< void >::control_block {
|
struct push_coroutine< void >::control_block {
|
||||||
pull_coroutine< void >::control_block * other;
|
pull_coroutine< void >::control_block * other;
|
||||||
boost::context::execution_context caller;
|
boost::context::execution_context caller;
|
||||||
boost::context::execution_context callee;
|
boost::context::execution_context callee;
|
||||||
bool preserve_fpu;
|
bool preserve_fpu;
|
||||||
int state;
|
int state;
|
||||||
|
std::exception_ptr except;
|
||||||
|
|
||||||
template< typename StackAllocator, typename Fn >
|
template< typename StackAllocator, typename Fn >
|
||||||
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
control_block( context::preallocated, StackAllocator, Fn &&, bool);
|
||||||
|
@ -46,6 +46,9 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -54,6 +57,7 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ),
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except(),
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +68,7 @@ push_coroutine< T >::control_block::control_block( typename pull_coroutine< T >:
|
|||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0),
|
state( 0),
|
||||||
|
except(),
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +91,9 @@ push_coroutine< T >::control_block::resume( T const& t_) {
|
|||||||
t = & tmp;
|
t = & tmp;
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
t = nullptr;
|
t = nullptr;
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
@ -101,6 +109,9 @@ push_coroutine< T >::control_block::resume( T && t_) {
|
|||||||
t = & tmp;
|
t = & tmp;
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
t = nullptr;
|
t = nullptr;
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
@ -133,6 +144,9 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -141,6 +155,7 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ),
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except(),
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,6 +166,7 @@ push_coroutine< T & >::control_block::control_block( typename pull_coroutine< T
|
|||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0),
|
state( 0),
|
||||||
|
except(),
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +186,9 @@ push_coroutine< T & >::control_block::resume( T & t_) {
|
|||||||
t = & t_;
|
t = & t_;
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
t = nullptr;
|
t = nullptr;
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
@ -200,6 +219,9 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
fn( synthesized);
|
fn( synthesized);
|
||||||
} catch ( forced_unwind const&) {
|
} catch ( forced_unwind const&) {
|
||||||
// do nothing for unwinding exception
|
// do nothing for unwinding exception
|
||||||
|
} catch (...) {
|
||||||
|
// store other exceptions in exception-pointer
|
||||||
|
except = std::current_exception();
|
||||||
}
|
}
|
||||||
// set termination flags
|
// set termination flags
|
||||||
state |= static_cast< int >( state_t::complete);
|
state |= static_cast< int >( state_t::complete);
|
||||||
@ -207,7 +229,8 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
|
BOOST_ASSERT_MSG( false, "push_coroutine is complete");
|
||||||
}),
|
}),
|
||||||
preserve_fpu( preserve_fpu_),
|
preserve_fpu( preserve_fpu_),
|
||||||
state( static_cast< int >( state_t::unwind) ) {
|
state( static_cast< int >( state_t::unwind) ),
|
||||||
|
except() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -216,7 +239,8 @@ push_coroutine< void >::control_block::control_block( pull_coroutine< void >::co
|
|||||||
caller( other->callee),
|
caller( other->callee),
|
||||||
callee( other->caller),
|
callee( other->caller),
|
||||||
preserve_fpu( other->preserve_fpu),
|
preserve_fpu( other->preserve_fpu),
|
||||||
state( 0) {
|
state( 0),
|
||||||
|
except() {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -233,6 +257,9 @@ inline
|
|||||||
void
|
void
|
||||||
push_coroutine< void >::control_block::resume() {
|
push_coroutine< void >::control_block::resume() {
|
||||||
callee( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
|
if ( except) {
|
||||||
|
std::rethrow_exception( except);
|
||||||
|
}
|
||||||
// test early-exit-flag
|
// test early-exit-flag
|
||||||
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
if ( 0 != ( ( other->state) & static_cast< int >( state_t::early_exit) ) ) {
|
||||||
throw forced_unwind();
|
throw forced_unwind();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user