diff --git a/include/ircd/ctx/shared_state.h b/include/ircd/ctx/shared_state.h index 3385b28d4..9b626c924 100644 --- a/include/ircd/ctx/shared_state.h +++ b/include/ircd/ctx/shared_state.h @@ -104,11 +104,21 @@ ircd::ctx::notify(shared_state &st) return; } - ircd::post([&st] + // Need a fresh stack to execute then(), not this ctx's. + ircd::post([&st]() noexcept { assert(bool(st.then)); - st.cond.notify_all(); st.then(st); + st.then = {}; + st.cond.notify_all(); + }); + + // If we don't hold the ctx here then it's too easy to destroy the future + // between now and when then() posts. This is completely effective if the + // future is on this ctx as long as then() itself doesn't hose it. + st.cond.wait([&st] + { + return !bool(st.then); }); }