State of context and coroutine
Hello, I find myself working on a project which makes use of boost::context functionality which got moved to the detail namespace somewhen before booost 1.61 . Now this project is mimicing something along the lines of boost::coroutine on top of context. I could try to adapt to the new intended usage of context or change the setup to use coroutine. Hence my question is whether the public coroutine interface, specifically the asymmetric parts, is stable yet? Im seeing 1's and 2's there side by side, so I could imagine there's still deciding on a good interface going on. Kind Regards, Michael
2016-06-30 11:02 GMT+02:00 Michael Steinberg
I could try to adapt to the new intended usage of context or change the setup to use coroutine.
The suspendedd context is passed as member of struct transfer_t. struct transfer_t will be passed as parameter to the context-fn if resuemd the first time or will be returned from jump_context() which suspended the context before (you could take a look at coroutine).
Hence my question is whether the public coroutine interface, specifically the asymmetric parts, is stable yet? I
yes, it's stable - but coroutine is deprecated in favour of coroutine2
On 1/07/2016 01:09, Oliver Kowalke wrote:
yes, it's stable - but coroutine is deprecated in favour of coroutine2
Unless you don't have access to a C++14 compiler :P Although on that note: http://www.boost.org/doc/libs/1_61_0/ states that Coroutine2 is a C++14 library. http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/ove... states that Coroutine2 is a C++11 library. Which of these is true? It also might be nice if the Overview (or other similar location) in Coroutine2 talks about the deprecation and/or what's different between the two libraries.
On 07/04/2016 12:42 AM, Gavin Lambert wrote:
On 1/07/2016 01:09, Oliver Kowalke wrote:
yes, it's stable - but coroutine is deprecated in favour of coroutine2
Unless you don't have access to a C++14 compiler :P
Although on that note:
http://www.boost.org/doc/libs/1_61_0/ states that Coroutine2 is a C++14 library.
http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/ove... states that Coroutine2 is a C++11 library.
Which of these is true?
Both. Reading the Boost 1.61 changelog:
http://www.boost.org/users/history/version_1_61_0.html
Context: - execution_context: relaxed to C++11 Coroutine2: - relaxed to C++11
It looks like Boost >=1.59, <1.61 has to be build with CXXFLAGS="-std=c++14", which is probably not the default. Failing to do so results in linker issues when using Boost.Coroutine2. Boost >=1.61 relaxes Boost.Coroutine2 to C++11.
It also might be nice if the Overview (or other similar location) in Coroutine2 talks about the deprecation and/or what's different between the two libraries.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
On 5/07/2016 00:38, Daniel Hofmann wrote:
On 07/04/2016 12:42 AM, Gavin Lambert wrote:
Although on that note:
http://www.boost.org/doc/libs/1_61_0/ states that Coroutine2 is a C++14 library.
http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/ove... states that Coroutine2 is a C++11 library.
Which of these is true?
Both.
Reading the Boost 1.61 changelog:
http://www.boost.org/users/history/version_1_61_0.html
Context: - execution_context: relaxed to C++11 Coroutine2: - relaxed to C++11
It looks like Boost >=1.59, <1.61 has to be build with CXXFLAGS="-std=c++14", which is probably not the default. Failing to do so results in linker issues when using Boost.Coroutine2.
Boost >=1.61 relaxes Boost.Coroutine2 to C++11.
Ok, but that's not "both", it means the first is wrong and should be corrected.
One remaining question/uncertainty: The documentation specifically states not to leak exceptions into the "stack base" or leaving entry function. On the other hand, stack unwinding works by throwing an exception (boost::context::detail::forced_unwind) ontop of the coroutine. That is a) not documented and b) the exception is defined in the detail namespace. That means, one has to use a detail-member to rethrow the one exception that has to leave the coroutine client entry function. I would argue to put the exception definition into the context namespace. Michael
2016-07-05 20:36 GMT+02:00 Michael Steinberg
a) not documented
http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/cor... 'Code executed by *coroutine-function* must not prevent the propagation of the *detail::forced_unwind* exception. Absorbing that exception will cause stack unwinding to fail. Thus, any code that catches all exceptions must re-throw any pending *detail::forced_unwind* exception.'
b) the exception is defined in the detail namespace. That means, one has to use a detail-member to rethrow the one exception that has to leave the coroutine client entry function.
do not absorb exception detail::forced_unwind, e.g. do not use 'catch(...)'
On 6/07/2016 17:40, Oliver Kowalke wrote:
b) the exception is defined in the detail namespace. That means, one has to use a detail-member to rethrow the one exception that has to leave the coroutine client entry function.
do not absorb exception detail::forced_unwind, e.g. do not use 'catch(...)'
It might be worthwhile mentioning in the docs that detail::forced_unwind is *not* derived from std::exception. (This is not currently obvious unless you look at the library code.) This means that code that uses "catch (const std::exception& e)" to catch all normal exceptions (rather than "catch(...)") will not catch forced_unwind and so doesn't need to be specially conditioned to rethrow it, and consequently doesn't need to know about the detail namespace.
2016-07-05 20:36 GMT+02:00 Michael Steinberg
mailto:michsteinb@gmail.com>: a) not documented
http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/cor... 'Code executed by /coroutine-function/ must not prevent the propagation of the /detail::forced_unwind/ exception. Absorbing that exception will cause stack unwinding to fail. Thus, any code that catches all exceptions must re-throw any pending /detail::forced_unwind/ exception.' Oh well, I should have noted that we're going directly with context::execution_context now, in whose documentation I could not find
this.
b) the exception is defined in the detail namespace. That means, one has to use a detail-member to rethrow the one exception that has to leave the coroutine client entry function.
do not absorb exception detail::forced_unwind, e.g. do not use 'catch(...)'
Can *any* exception *but* detail::forced_unwind leak the coroutine (not meaning coroutine::*) that is being driven by context::execution_context without crashing ungracefully? I'm not sure how I could guarantee that without a pattern like "catch( forced_unwind& ) { throw; } catch ( ... ) { ... }". But that can very well be the case, because I'm not so very used to "using" exceptions other than trying my best to write exception-safe code. I should also say that I would never swallow with catch( ... ), it's just that here I did not see any other generic solution. Michael
2016-07-06 9:49 GMT+02:00 Michael Steinberg
2016-07-05 20:36 GMT+02:00 Michael Steinberg
: a) not documented
http://www.boost.org/doc/libs/1_61_0/libs/coroutine2/doc/html/coroutine2/cor... 'Code executed by *coroutine-function* must not prevent the propagation of the *detail::forced_unwind* exception. Absorbing that exception will cause stack unwinding to fail. Thus, any code that catches all exceptions must re-throw any pending *detail::forced_unwind* exception.'
Oh well, I should have noted that we're going directly with context::execution_context now, in whose documentation I could not find this.
execution_context does not unwind the stack - the user is responsible for this http://www.boost.org/doc/libs/1_61_0/libs/context/doc/html/context/ecv2.html 'Sometimes it is necessary to unwind the stack of an unfinished context to destroy local stack variables so they can release allocated resources (RAII pattern). The user is responsible for this task.'
execution_context does not unwind the stack - the user is responsible for this http://www.boost.org/doc/libs/1_61_0/libs/context/doc/html/context/ecv2.html 'Sometimes it is necessary to unwind the stack of an unfinished context to destroy local stack variables so they can release allocated resources (RAII pattern). The user is responsible for this task.' Hrmm, I remember stumbling across that part of the documentation, for wondering what it means exactly, since my copy of execution_context_v2.hpp contains
<<<<<< code <<<< ~execution_context() { if ( nullptr != fctx_) { detail::ontop_fcontext( detail::exchange( fctx_, nullptr), nullptr, detail::context_unwind); } } <<<<<< code <<<<
execution_context v1: user is responsible to unwind the stack execution_context v2: if the instance of execution_context is destructed while the context is suspended inside the context-fn, the stack is unwound -> see coroutine2
participants (4)
-
Daniel Hofmann
-
Gavin Lambert
-
Michael Steinberg
-
Oliver Kowalke