auto unwind in coroutine_context (no manual dtor), clean up generator
parent
c2b82771f9
commit
b63729641b
|
@ -366,10 +366,6 @@ public:
|
|||
c.p_func = nullptr;
|
||||
}
|
||||
|
||||
~coroutine() {
|
||||
this->unwind();
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return !this->is_dead();
|
||||
}
|
||||
|
@ -480,10 +476,6 @@ public:
|
|||
c.p_result = nullptr;
|
||||
}
|
||||
|
||||
~generator() {
|
||||
this->unwind();
|
||||
}
|
||||
|
||||
explicit operator bool() const noexcept {
|
||||
return !this->is_dead();
|
||||
}
|
||||
|
@ -510,7 +502,7 @@ public:
|
|||
}
|
||||
|
||||
bool empty() const noexcept {
|
||||
return (!p_result || this->is_dead());
|
||||
return !p_result;
|
||||
}
|
||||
|
||||
generator_range<T> iter() noexcept;
|
||||
|
@ -529,6 +521,8 @@ public:
|
|||
private:
|
||||
void resume_call() {
|
||||
p_func(yield_type{*this});
|
||||
/* done, gotta null the item so that empty() returns true */
|
||||
p_result = nullptr;
|
||||
}
|
||||
|
||||
std::function<void(yield_type)> p_func;
|
||||
|
|
|
@ -42,6 +42,9 @@ transfer_t OSTD_CDECL ostd_ontop_fcontext(
|
|||
struct coroutine_context {
|
||||
protected:
|
||||
coroutine_context() {}
|
||||
~coroutine_context() {
|
||||
unwind();
|
||||
}
|
||||
|
||||
coroutine_context(coroutine_context const &) = delete;
|
||||
coroutine_context(coroutine_context &&c):
|
||||
|
@ -69,29 +72,6 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
void unwind() {
|
||||
if (is_dead()) {
|
||||
/* this coroutine was either initialized with a null function or
|
||||
* it's already terminated and thus its stack has already unwound
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (!p_orig) {
|
||||
/* this coroutine never got to live :(
|
||||
* let it call the entry point at least this once...
|
||||
* this will kill the stack so we don't leak memory
|
||||
*/
|
||||
coro_jump();
|
||||
return;
|
||||
}
|
||||
ostd_ontop_fcontext(
|
||||
std::exchange(p_coro, nullptr), nullptr,
|
||||
[](transfer_t t) -> transfer_t {
|
||||
throw forced_unwind{t.ctx};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void coro_jump() {
|
||||
p_coro = ostd_jump_fcontext(p_coro, this).ctx;
|
||||
}
|
||||
|
@ -149,6 +129,29 @@ private:
|
|||
HOLD = 0, EXEC, TERM
|
||||
};
|
||||
|
||||
void unwind() {
|
||||
if (is_dead()) {
|
||||
/* this coroutine was either initialized with a null function or
|
||||
* it's already terminated and thus its stack has already unwound
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (!p_orig) {
|
||||
/* this coroutine never got to live :(
|
||||
* let it call the entry point at least this once...
|
||||
* this will kill the stack so we don't leak memory
|
||||
*/
|
||||
coro_jump();
|
||||
return;
|
||||
}
|
||||
ostd_ontop_fcontext(
|
||||
std::exchange(p_coro, nullptr), nullptr,
|
||||
[](transfer_t t) -> transfer_t {
|
||||
throw forced_unwind{t.ctx};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template<typename SA>
|
||||
void finish() {
|
||||
set_dead();
|
||||
|
|
Loading…
Reference in New Issue