class interrupt_flag { std::atomic flag; std::condition_variable* thread_cond; std::condition_variable_any* thread_cond_any; std::mutex set_clear_mutex; public: interrupt_flag(): Interrupting threads thread_cond(0),thread_cond_any(0) {} void set() { flag.store(true,std::memory_order_relaxed); std::lock_guard lk(set_clear_mutex); if(thread_cond) { thread_cond->notify_all(); } else if(thread_cond_any) { thread_cond_any->notify_all(); } } template void wait(std::condition_variable_any& cv,Lockable& lk) { struct custom_lock { interrupt_flag* self; Lockable& lk; custom_lock(interrupt_flag* self_, std::condition_variable_any& cond, Lockable& lk_): self(self_),lk(lk_) { self->set_clear_mutex.lock(); self->thread_cond_any=&cond; } void unlock() { lk.unlock(); self->set_clear_mutex.unlock(); } void lock() { std::lock(self->set_clear_mutex,lk); } ~custom_lock() { self->thread_cond_any=0; self->set_clear_mutex.unlock(); } }; custom_lock cl(this,cv,lk); interruption_point(); cv.wait(cl); interruption_point(); } // rest as before }; template void interruptible_wait(std::condition_variable_any& cv, Lockable& lk) { this_thread_interrupt_flag.wait(cv,lk); }