mirror of
https://github.com/boostorg/coroutine2.git
synced 2025-05-09 23:24:01 +00:00
Merge branch 'develop'
This commit is contained in:
commit
47219de46b
@ -49,5 +49,7 @@ int main(int argc,char* argv[]){
|
|||||||
|
|
||||||
std::copy(begin(words),end(words),begin(writer));
|
std::copy(begin(words),end(words),begin(writer));
|
||||||
|
|
||||||
|
std::cout << "\nDone" << std::endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ 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);
|
||||||
@ -51,7 +50,6 @@ 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);
|
||||||
@ -74,7 +72,6 @@ struct pull_coroutine< void >::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);
|
||||||
|
@ -36,29 +36,25 @@ pull_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized push_coroutine< T >
|
||||||
|
typename push_coroutine< T >::control_block synthesized_cb( this);
|
||||||
|
push_coroutine< T > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized push_coroutine< T >
|
|
||||||
typename push_coroutine< T >::control_block synthesized_cb( this);
|
|
||||||
push_coroutine< T > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized push_coroutine as argument
|
// call coroutine-fn with synthesized push_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
// jump back to caller
|
||||||
caller.resume( preserve_fpu);
|
caller( preserve_fpu);
|
||||||
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.resume( preserve_fpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
@ -67,8 +63,7 @@ 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 >
|
||||||
@ -77,17 +72,14 @@ pull_coroutine< T >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
void
|
void
|
||||||
pull_coroutine< T >::control_block::resume() {
|
pull_coroutine< T >::control_block::resume() {
|
||||||
callee.resume( 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();
|
||||||
@ -111,29 +103,25 @@ pull_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized push_coroutine< T >
|
||||||
|
typename push_coroutine< T & >::control_block synthesized_cb( this);
|
||||||
|
push_coroutine< T & > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized push_coroutine< T >
|
|
||||||
typename push_coroutine< T & >::control_block synthesized_cb( this);
|
|
||||||
push_coroutine< T & > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized push_coroutine as argument
|
// call coroutine-fn with synthesized push_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
// jump back to caller
|
||||||
caller.resume( preserve_fpu);
|
caller( preserve_fpu);
|
||||||
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.resume( preserve_fpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
@ -142,8 +130,7 @@ 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 >
|
||||||
@ -152,17 +139,14 @@ pull_coroutine< T & >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
void
|
void
|
||||||
pull_coroutine< T & >::control_block::resume() {
|
pull_coroutine< T & >::control_block::resume() {
|
||||||
callee.resume( 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();
|
||||||
@ -185,29 +169,25 @@ pull_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized push_coroutine< T >
|
||||||
|
typename push_coroutine< void >::control_block synthesized_cb( this);
|
||||||
|
push_coroutine< void > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized push_coroutine< T >
|
|
||||||
typename push_coroutine< void >::control_block synthesized_cb( this);
|
|
||||||
push_coroutine< void > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized push_coroutine as argument
|
// call coroutine-fn with synthesized push_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
// jump back to caller
|
||||||
caller.resume( preserve_fpu);
|
caller( preserve_fpu);
|
||||||
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.resume( preserve_fpu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
@ -216,8 +196,7 @@ 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
|
||||||
@ -226,17 +205,14 @@ pull_coroutine< void >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
pull_coroutine< void >::control_block::resume() {
|
pull_coroutine< void >::control_block::resume() {
|
||||||
callee.resume( 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,7 +27,6 @@ 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 >
|
||||||
@ -54,7 +53,6 @@ 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 >
|
||||||
@ -78,7 +76,6 @@ struct push_coroutine< void >::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);
|
||||||
|
@ -37,28 +37,23 @@ push_coroutine< T >::control_block::control_block( context::preallocated palloc,
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized pull_coroutine< T >
|
||||||
|
typename pull_coroutine< T >::control_block synthesized_cb( this);
|
||||||
|
pull_coroutine< T > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized pull_coroutine< T >
|
|
||||||
typename pull_coroutine< T >::control_block synthesized_cb( this);
|
|
||||||
pull_coroutine< T > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized pull_coroutine as argument
|
// call coroutine-fn with synthesized pull_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
caller( preserve_fpu);
|
||||||
caller.resume( preserve_fpu_);
|
|
||||||
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(),
|
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,7 +64,6 @@ 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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +73,7 @@ push_coroutine< T >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,11 +84,8 @@ push_coroutine< T >::control_block::resume( T const& t_) {
|
|||||||
// pass an pointer (address of tmp) to other context
|
// pass an pointer (address of tmp) to other context
|
||||||
T tmp( t_);
|
T tmp( t_);
|
||||||
t = & tmp;
|
t = & tmp;
|
||||||
callee.resume( 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();
|
||||||
@ -108,11 +99,8 @@ push_coroutine< T >::control_block::resume( T && t_) {
|
|||||||
// pass an pointer (address of tmp) to other context
|
// pass an pointer (address of tmp) to other context
|
||||||
T tmp( std::move( t_) );
|
T tmp( std::move( t_) );
|
||||||
t = & tmp;
|
t = & tmp;
|
||||||
callee.resume( 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();
|
||||||
@ -136,28 +124,23 @@ push_coroutine< T & >::control_block::control_block( context::preallocated pallo
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized pull_coroutine< T >
|
||||||
|
typename pull_coroutine< T & >::control_block synthesized_cb( this);
|
||||||
|
pull_coroutine< T & > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized pull_coroutine< T >
|
|
||||||
typename pull_coroutine< T & >::control_block synthesized_cb( this);
|
|
||||||
pull_coroutine< T & > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized pull_coroutine as argument
|
// call coroutine-fn with synthesized pull_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
caller( preserve_fpu);
|
||||||
caller.resume( preserve_fpu_);
|
|
||||||
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(),
|
|
||||||
t( nullptr) {
|
t( nullptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +151,6 @@ 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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +160,7 @@ push_coroutine< T & >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,11 +168,8 @@ template< typename T >
|
|||||||
void
|
void
|
||||||
push_coroutine< T & >::control_block::resume( T & t_) {
|
push_coroutine< T & >::control_block::resume( T & t_) {
|
||||||
t = & t_;
|
t = & t_;
|
||||||
callee.resume( 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();
|
||||||
@ -212,28 +191,23 @@ push_coroutine< void >::control_block::control_block( context::preallocated pall
|
|||||||
caller( boost::context::execution_context::current() ),
|
caller( boost::context::execution_context::current() ),
|
||||||
callee( palloc, salloc,
|
callee( palloc, salloc,
|
||||||
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
[=,fn=std::forward< Fn >( fn_)] () mutable {
|
||||||
|
// create synthesized pull_coroutine< T >
|
||||||
|
typename pull_coroutine< void >::control_block synthesized_cb( this);
|
||||||
|
pull_coroutine< void > synthesized( & synthesized_cb);
|
||||||
|
other = & synthesized_cb;
|
||||||
try {
|
try {
|
||||||
// create synthesized pull_coroutine< T >
|
|
||||||
typename pull_coroutine< void >::control_block synthesized_cb( this);
|
|
||||||
pull_coroutine< void > synthesized( & synthesized_cb);
|
|
||||||
other = & synthesized_cb;
|
|
||||||
// call coroutine-fn with synthesized pull_coroutine as argument
|
// call coroutine-fn with synthesized pull_coroutine as argument
|
||||||
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);
|
||||||
// jump back to caller
|
caller( preserve_fpu);
|
||||||
caller.resume( preserve_fpu_);
|
|
||||||
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
|
||||||
@ -242,8 +216,7 @@ 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
|
||||||
@ -252,17 +225,14 @@ push_coroutine< void >::control_block::~control_block() {
|
|||||||
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
0 != ( state & static_cast< int >( state_t::unwind) ) ) {
|
||||||
// set early-exit flag
|
// set early-exit flag
|
||||||
state |= static_cast< int >( state_t::early_exit);
|
state |= static_cast< int >( state_t::early_exit);
|
||||||
callee.resume( preserve_fpu);
|
callee( preserve_fpu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
push_coroutine< void >::control_block::resume() {
|
push_coroutine< void >::control_block::resume() {
|
||||||
callee.resume( 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();
|
||||||
|
@ -461,8 +461,8 @@ void test_unwind()
|
|||||||
|
|
||||||
void test_exceptions()
|
void test_exceptions()
|
||||||
{
|
{
|
||||||
bool thrown = false;
|
std::string msg("abc"), value;
|
||||||
std::runtime_error ex("abc");
|
std::runtime_error ex( msg);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
coro::coroutine< void >::push_type coro(
|
coro::coroutine< void >::push_type coro(
|
||||||
@ -472,13 +472,9 @@ void test_exceptions()
|
|||||||
BOOST_CHECK( ! coro);
|
BOOST_CHECK( ! coro);
|
||||||
BOOST_CHECK( false);
|
BOOST_CHECK( false);
|
||||||
}
|
}
|
||||||
catch ( std::runtime_error const&)
|
catch ( std::runtime_error const& ex)
|
||||||
{ thrown = true; }
|
{ value = ex.what(); }
|
||||||
catch ( std::exception const&)
|
BOOST_CHECK_EQUAL( value, msg);
|
||||||
{}
|
|
||||||
catch (...)
|
|
||||||
{}
|
|
||||||
BOOST_CHECK( thrown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_input_iterator()
|
void test_input_iterator()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user