mirror of
https://github.com/scylladb/scylladb.git
synced 2026-04-19 16:15:07 +00:00
drain() signals the postponed_reevaluation condition variable to terminate the postponed_compactions_reevaluation() coroutine but does not await its completion. When enable() is called afterwards, it overwrites _waiting_reevalution with a new coroutine, orphaning the old one. During shutdown, really_do_stop() only awaits the latest coroutine via _waiting_reevalution, leaving the orphaned coroutine still alive. After sharded::stop() destroys the compaction_manager, the orphaned coroutine resumes and reads freed memory (is_disabled() accesses _state). Fix by introducing stop_postponed_compactions(), awaiting the reevaluation coroutine in both drain() and stop() after signaling it, if postponed_compactions_reevaluation() is running. It uses an std::optional<future<>> for _waiting_reevalution and std::exchange to leave _waiting_reevalution disengaged when postponed_compactions_reevaluation() is not running. This prevents a race between drain() and stop(). While at it, fix typo in _waiting_reevalution -> _waiting_reevaluation. Fixes: SCYLLADB-1463 Signed-off-by: Benny Halevy <bhalevy@scylladb.com> Closes scylladb/scylladb#29443