Skip to content

Commit

Permalink
function executed by resume_with() has to return a continuation
Browse files Browse the repository at this point in the history
  • Loading branch information
olk committed Aug 10, 2017
1 parent 8346fbf commit 420554f
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 31 deletions.
6 changes: 4 additions & 2 deletions doc/callcc.qbk
Expand Up @@ -176,6 +176,7 @@ return `void`.
c=c.resume_with([&data](ctx::continuation && c){
std::cout << "f2: entered: " << data << std::endl;
data=-1;
return std::move( c);
});
std::cout << "f1: returned third time" << std::endl;

Expand Down Expand Up @@ -221,6 +222,7 @@ an exception.
c = c.resume_with(
[](ctx::continuation && c){
throw my_exception(std::move(c),"abc");
return std::move( c);
});

output:
Expand Down Expand Up @@ -527,11 +529,11 @@ e.g. ['continuation::operator bool()] returns `true`.]]

[variablelist
[[Effects:] [Captures current continuation and resumes `*this`.
The function `resume_with`, is used to execute function `fn` in continuation
The function `resume_with`, is used to execute function `fn` in the execution context of
`*this` (e.g. the stack frame of `fn` is allocated on stack of `*this`).]]
[[Returns:] [The continuation representing the continuation that has been
suspended.]]
[[Note:] [Function `fn` needs to return void.]]
[[Note:] [Function `fn` needs to return `continuation`.]]
[[Note:] [The returned continuation indicates if the suspended continuation has
terminated (return from context-function) via `bool operator()`.]]
]
Expand Down
1 change: 1 addition & 0 deletions example/ontop.cpp
Expand Up @@ -32,6 +32,7 @@ int main() {
c = c.resume_with( [&data](ctx::continuation && c){
std::cout << "f2: entered: " << data << std::endl;
data = -1;
return std::move( c);
});
std::cout << "f1: returned third time" << std::endl;
std::cout << "main: done" << std::endl;
Expand Down
3 changes: 2 additions & 1 deletion example/ontop_void.cpp
Expand Up @@ -21,8 +21,9 @@ ctx::continuation f1( ctx::continuation && c) {
return std::move( c);
}

void f2( ctx::continuation && c) {
ctx::continuation f2( ctx::continuation && c) {
std::cout << "f2: entered" << std::endl;
return std::move( c);
}

int main() {
Expand Down
1 change: 1 addition & 0 deletions example/throw.cpp
Expand Up @@ -38,6 +38,7 @@ int main() {
c = c.resume_with(
[](ctx::continuation && c){
throw my_exception(std::move( c), "abc");
return std::move( c);
});

std::cout << "main: done" << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion include/boost/context/continuation_fcontext.hpp
Expand Up @@ -95,7 +95,7 @@ transfer_t context_ontop( transfer_t t) {
t.data = nullptr;
Ctx c{ t.fctx };
// execute function, pass continuation via reference
fn( std::move( c) );
c = fn( std::move( c) );
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
return { exchange( c.fctx_, nullptr), nullptr };
#else
Expand Down
40 changes: 25 additions & 15 deletions include/boost/context/continuation_ucontext.hpp
Expand Up @@ -84,18 +84,18 @@ static void entry_func( void * data) noexcept {
struct BOOST_CONTEXT_DECL activation_record {
thread_local static activation_record * current_rec;

ucontext_t uctx{};
stack_context sctx{};
bool main_ctx{ true };
activation_record * from{ nullptr };
std::function< void(activation_record*&) > ontop{};
bool terminated{ false };
bool force_unwind{ false };
ucontext_t uctx{};
stack_context sctx{};
bool main_ctx{ true };
activation_record * from{ nullptr };
std::function< activation_record*(activation_record*&) > ontop{};
bool terminated{ false };
bool force_unwind{ false };
#if defined(BOOST_USE_ASAN)
void * fake_stack{ nullptr };
void * stack_bottom{ nullptr };
std::size_t stack_size{ 0 };
bool started{ false };
void * fake_stack{ nullptr };
void * stack_bottom{ nullptr };
std::size_t stack_size{ 0 };
bool started{ false };
#endif

static activation_record *& current() noexcept;
Expand Down Expand Up @@ -168,20 +168,30 @@ struct BOOST_CONTEXT_DECL activation_record {
current()->ontop = std::bind(
[](typename std::decay< Fn >::type & fn, activation_record *& ptr){
Ctx c{ ptr };
fn( std::move( c) );
c = fn( std::move( c) );
if ( ! c) {
ptr = nullptr;
}
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
return exchange( c.ptr_, nullptr);
#else
return std::exchange( c.ptr_, nullptr);
#endif
},
std::forward< Fn >( fn),
std::placeholders::_1);
#else
current()->ontop = [fn=std::forward<Fn>(fn)](activation_record *& ptr){
Ctx c{ ptr };
fn( std::move( c) );
c = fn( std::move( c) );
if ( ! c) {
ptr = nullptr;
}
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
return exchange( c.ptr_, nullptr);
#else
return std::exchange( c.ptr_, nullptr);
#endif
};
#endif
#if defined(BOOST_USE_SEGMENTED_STACKS)
Expand Down Expand Up @@ -408,7 +418,7 @@ class BOOST_CONTEXT_DECL continuation {
if ( BOOST_UNLIKELY( detail::activation_record::current()->force_unwind) ) {
throw detail::forced_unwind{ ptr};
} else if ( BOOST_UNLIKELY( nullptr != detail::activation_record::current()->ontop) ) {
detail::activation_record::current()->ontop( ptr);
ptr = detail::activation_record::current()->ontop( ptr);
detail::activation_record::current()->ontop = nullptr;
}
return continuation{ ptr };
Expand All @@ -426,7 +436,7 @@ class BOOST_CONTEXT_DECL continuation {
if ( BOOST_UNLIKELY( detail::activation_record::current()->force_unwind) ) {
throw detail::forced_unwind{ ptr};
} else if ( BOOST_UNLIKELY( nullptr != detail::activation_record::current()->ontop) ) {
detail::activation_record::current()->ontop( ptr);
ptr = detail::activation_record::current()->ontop( ptr);
detail::activation_record::current()->ontop = nullptr;
}
return continuation{ ptr };
Expand Down
32 changes: 21 additions & 11 deletions include/boost/context/continuation_winfib.hpp
Expand Up @@ -65,13 +65,13 @@ static VOID WINAPI entry_func( LPVOID data) noexcept {
struct BOOST_CONTEXT_DECL activation_record {
thread_local static activation_record * current_rec;

LPVOID fiber{ nullptr };
stack_context sctx{};
bool main_ctx{ true };
activation_record * from{ nullptr };
std::function< void(activation_record*&) > ontop{};
bool terminated{ false };
bool force_unwind{ false };
LPVOID fiber{ nullptr };
stack_context sctx{};
bool main_ctx{ true };
activation_record * from{ nullptr };
std::function< activation_record*(activation_record*&) > ontop{};
bool terminated{ false };
bool force_unwind{ false };

static activation_record *& current() noexcept;

Expand Down Expand Up @@ -142,20 +142,30 @@ struct BOOST_CONTEXT_DECL activation_record {
current()->ontop = std::bind(
[](typename std::decay< Fn >::type & fn, activation_record *& ptr){
Ctx c{ ptr };
fn( std::move( c) );
c = fn( std::move( c) );
if ( ! c) {
ptr = nullptr;
}
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
return exchange( c.ptr_, nullptr);
#else
return std::exchange( c.ptr_, nullptr);
#endif
},
std::forward< Fn >( fn),
std::placeholders::_1);
#else
current()->ontop = [fn=std::forward<Fn>(fn)](activation_record *& ptr){
Ctx c{ ptr };
fn( std::move( c) );
c = fn( std::move( c) );
if ( ! c) {
ptr = nullptr;
}
#if defined(BOOST_NO_CXX14_STD_EXCHANGE)
return exchange( c.ptr_, nullptr);
#else
return std::exchange( c.ptr_, nullptr);
#endif
};
#endif
// context switch
Expand Down Expand Up @@ -336,7 +346,7 @@ class BOOST_CONTEXT_DECL continuation {
if ( BOOST_UNLIKELY( detail::activation_record::current()->force_unwind) ) {
throw detail::forced_unwind{ ptr};
} else if ( BOOST_UNLIKELY( nullptr != detail::activation_record::current()->ontop) ) {
detail::activation_record::current()->ontop( ptr);
ptr = detail::activation_record::current()->ontop( ptr);
detail::activation_record::current()->ontop = nullptr;
}
return continuation{ ptr };
Expand All @@ -354,7 +364,7 @@ class BOOST_CONTEXT_DECL continuation {
if ( BOOST_UNLIKELY( detail::activation_record::current()->force_unwind) ) {
throw detail::forced_unwind{ ptr};
} else if ( BOOST_UNLIKELY( nullptr != detail::activation_record::current()->ontop) ) {
detail::activation_record::current()->ontop( ptr);
ptr = detail::activation_record::current()->ontop( ptr);
detail::activation_record::current()->ontop = nullptr;
}
return continuation{ ptr };
Expand Down
5 changes: 4 additions & 1 deletion test/test_callcc.cpp
Expand Up @@ -252,6 +252,7 @@ void test_ontop() {
c = c.resume_with(
[&i](ctx::continuation && c){
i -= 10;
return std::move( c);
});
BOOST_CHECK( c);
BOOST_CHECK_EQUAL( i, 200);
Expand All @@ -266,6 +267,7 @@ void test_ontop() {
c = c.resume_with(
[&c1](ctx::continuation && c){
c1 = std::move( c);
return std::move( c);
});
}
}
Expand All @@ -290,7 +292,8 @@ void test_ontop_exception() {
const char * what = "hello world";
c.resume_with(
[what](ctx::continuation && c){
throw my_exception( std::move( c), what);
throw my_exception( std::move( c), what);
return std::move( c);
});
BOOST_CHECK_EQUAL( 3, value1);
BOOST_CHECK_EQUAL( std::string( what), value2);
Expand Down

0 comments on commit 420554f

Please sign in to comment.