auto unwind in coroutine_context (no manual dtor), clean up generator

master
Daniel Kolesa 2017-03-13 17:29:48 +01:00
parent c2b82771f9
commit b63729641b
2 changed files with 29 additions and 32 deletions

View File

@ -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;

View File

@ -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();