/** 参数包装 **/
typedef std::tuple< Args ... > args_tpl_t;
/** 返回值包装 **/
typedef std::tuple< execution_context, typename std::decay< Args >::type ... > ret_tpl_t;
/** 用于记录栈地址,入口函数和参数的对象 **/
typedef record< Ctx, StackAlloc, Fn, Params ... > record_t;
// ========== 调用jump_fcontext - context_create函数内 ==========
// create fast-context
const fcontext_t fctx = make_fcontext( sp, size, & context_entry< record_t >);
BOOST_ASSERT( nullptr != fctx);
// placment new for control structure on context-stack
auto rec = ::new ( sp) record_t{
sctx, salloc, std::forward< Fn >( fn), std::forward< Params >( params) ... };
// transfer control structure to context-stack
return jump_fcontext( fctx, rec).fctx;
// ========== 调用jump_fcontext - ret_tpl_t operator()( Args ... args)函数内 ==========
ret_tpl_t operator()( Args ... args) {
BOOST_ASSERT( nullptr != fctx_);
args_tpl_t data( std::forward< Args >( args) ... );
detail::transfer_t t = detail::jump_fcontext( detail::exchange( fctx_, nullptr), & data);
if ( nullptr != t.data) {
data = std::move( * static_cast< args_tpl_t * >( t.data) );
}
return std::tuple_cat( std::forward_as_tuple( execution_context( t.fctx) ), std::move( data) );
}
// ========== 通过jump_fcontext第一次跳入 ==========
template< typename Rec >
void context_entry( transfer_t t_) noexcept {
// transfer control structure to the context-stack
Rec * rec = static_cast< Rec * >( t_.data);
BOOST_ASSERT( nullptr != rec);
transfer_t t = { nullptr, nullptr };
try {
// jump back to `context_create()`
t = jump_fcontext( t_.fctx, nullptr);
// start executing
t = rec->run( t);
} catch ( forced_unwind const& e) {
t = { e.fctx, nullptr };
}
BOOST_ASSERT( nullptr != t.fctx);
// destroy context-stack of `this`context on next context
ontop_fcontext( t.fctx, rec, context_exit< Rec >);
BOOST_ASSERT_MSG( false, "context already terminated");
}
// ========== 调用ontop_fcontext ==========
template< typename Fn >
ret_tpl_t operator()( exec_ontop_arg_t, Fn && fn, Args ... args) {
BOOST_ASSERT( nullptr != fctx_);
args_tpl_t data{ std::forward< Args >( args) ... };
auto p = std::make_tuple( fn, std::move( data) ); // 透传类型是 std::tuple<Fn, args_tpl_t>
detail::transfer_t t = detail::ontop_fcontext(
detail::exchange( fctx_, nullptr), // 跳入fctx_并把fctx_置空
& p,
detail::context_ontop< execution_context, Fn, Args ... >);
if ( nullptr != t.data) {
data = std::move( * static_cast< args_tpl_t * >( t.data) );
}
return std::tuple_cat( std::forward_as_tuple( execution_context( t.fctx) ), std::move( data) );
}
// ========== 通过ontop_fcontext跳入 ==========
template< typename Ctx, typename Fn, typename ... Args >
transfer_t context_ontop( transfer_t t) {
auto tpl = static_cast< std::tuple< Fn, std::tuple< Args ... > > * >( t.data);
BOOST_ASSERT( nullptr != tpl);
typename std::decay< Fn >::type fn = std::forward< Fn >( std::get< 0 >( * tpl) );
auto args = std::move( std::get< 1 >( * tpl) );
Ctx ctx{ t.fctx };
// execute function
auto result = apply( // apply的作用是展开并调用fn函数: fn(ctx, unpack(args))
fn,
std::tuple_cat(
std::forward_as_tuple( std::move( ctx) ),
std::move( args) ) );
ctx = std::move( std::get< 0 >( result) );
// apply returned data
detail::tail( args) = std::move( result);
std::get< 1 >( * tpl) = std::move( args);
return { exchange( ctx.fctx_, nullptr), & std::get< 1 >( * tpl) };
}