
The mechanism in LEAF for dealing with this sort of thing is to manually activate/deactivate a leaf::context<>. The general architecture of LEAF is this: there are one or more leaf::context<E1, E2, ...> objects (think something similar to std::tuple<E1, E2, ...>) at different error-handling scopes in the call stack. When a context<E1, E2, ...> is activated, TLS pointers of the E1, E2, ... types are pointed to the E1, E2, ... objects in that context. This binds the context<> object to the calling thread and, from this point on, the TLS pointers are used to transport the error objects when reported. When control returns to the error-handling scope -- where the leaf::context<> resides -- it is deactivated before errors are handled Normally, users don't deal with leaf::context<> directly, but it is part of the API and you can just make a context<>, activate it as needed to collect error objects, then deactivate it and, if there was an error, move it elsewhere to handle errors (if no error, you can just activate it again the next time). So, when I say it doesn't work well with coroutines, what I mean is it won't "just work", not that you can't use it. On Tue, May 5, 2020 at 6:59 AM Niall Douglas via Boost < boost@lists.boost.org> wrote:
On 04/05/2020 01:40, Emil Dotchevski via Boost wrote:
LEAF is not suitable for coroutines
I cannot see any good reason why LEAF could not transport the current tree of LEAF state within a C++ Coroutine across kernel threads.
Rough implementation:
1. Traverse the current LEAF state in the current C++ Coroutine.
2. Suspend the current C++ coroutine, resume an internal checking C++ Coroutine.
3. Traverse the current LEAF state from within the internal checking C++ Coroutine.
4. Compare this LEAF state with the previous one. If some of the LEAF state "escapes" the previous Coroutine, resume the original C++ Coroutine and report failure, as this LEAF state cannot be transported between kernel threads.
5. Otherwise transporting LEAF state with the current C++ coroutine ought to be as simple as restamping the head TLS pointer to the current LEAF state when one resumes Coroutine execution in another kernel thread (i.e. squirrel away the head TLS pointer into the C++ coroutine frame, restore it upon resumption)
6. For convenience, wrap up all of the above into C++ coroutine awaitables which self-specialise when they see a T which is a LEAF result e.g. boost::leaf::awaitables::lazy<T>. You may find inspiration in the implementation code for outcome::awaitables::lazy<T>, as Outcome provides Outcome-specialising awaitable types.
As an aside, Outcome did not support C++ Coroutines originally as I did not expect much demand for such support. I assumed that given the poor QoI of C++ Coroutines in all the major implementations nobody would deploy production software using them.
It turns out I was wrong on that. Outcome + C++ Coroutines is surprisingly popular. And even I have ended up using it personally in test code (I still think Coroutines are not production ready).
I would expect that if LEAF is accepted, you will see the same.
Niall
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost