Is there any method that causes the reversal of entire stacks in C ++? (except for the exception)

I wrote a sequel - in a specific coroutine library. It is similar to std :: thread (except that it is cooperative) - each execution context is represented in a continuation object.

The problem is the destruction of the continuation object. If the dtor for the continuation object is called before the execution context exits gracefully, it must be forcibly closed by the context that destroys the object.

This way, every C ++ object in the stack stack will not be destroyed properly. This may be a pleasant situation for someone - so I decided to find a solution.

The first time I thought of using an exception to expand a stack frame, as shown below. (Note that the following is only the erroneous psuedo code.)

coroutine::~coroutine() { status = FORCED_EXIT; switch_to(*this); } void coroutine::yield(coroutine& other_coroutine) { // switch to other context, halt until invocation by other context switch_to(other_coroutine); if (status_ != FORCED_EXIT) { return; // resume } else { throw ContextClosingException; } } void coroutine::entrypoint() { try { entry_function_(); } catch(ContextClosingException& e) { switch_to(caller_coroutine); } } 

However, I found a critical flaw. Any custom code that โ€œrules out swallowing,โ€ as shown below, will completely violate the joint planning assumption.

 try { ... } catch(...) { // ContextClosingException // do nothing, just swallow exception. } 

So, I need to find another way to cause the stack to expand (or any other way to destroy the stack object in the sequel). A standard matching method would be nice - but the implementation of the continuation itself depends on the platform-specific API, so an unattractive way would be acceptable. (I am using win32)

+4
source share
1 answer

There is nothing in the C ++ standard, which allows you to expand the stack, with the exception of exceptions. Coroutines (or corountines support) can be offered after C ++ 11 (this was discussed during the Going Native conference).

You will need to use OS-based calls (if they exist, and I donโ€™t think so), but most likely you are on your own with ASM. You can take a look at the boost.context library for a typical solution.

+1
source

Source: https://habr.com/ru/post/1396538/


All Articles