https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99979
Bug ID: 99979 Summary: condition_variable_any has wrong behavior if Lock::lock() throws Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redbeard0531 at gmail dot com Target Milestone: --- https://eel.is/c++draft/thread.condvarany.wait says "Postconditions: lock is locked by the calling thread. […] Remarks: If the function fails to meet the postcondition, terminate() is invoked […] This can happen if the re-locking of the mutex throws an exception." This wording was changed in C++14 for https://cplusplus.github.io/LWG/issue2135, but given that it is borderline impossible to use a condition_variable[_any] correctly if it doesn't guarantee relocking, it seems best to do the same in C++11 mode as well. Unfortunately, std::condition_variable_any::__Unlock::~__Unlock() either ignores[1] or propagates any exception thrown by lock(), which means that the postcondition of wait() may not be fulfilled. I think the correct behavior would be to remove the noexcept(false), allowing the destructor's default noexecpt to apply, and just unconditionally call _M_lock.lock() without any try/catch. [1] It ignores if std::uncaught_exception() returns true. I'm not 100% sure why that dispatch is there. It seems like it may be trying to detect if _M_cond.wait() threw, but a) that is noexcept and b) that doesn't work correctly if some thread waits on a condvar inside a destructor that is triggered during exception unwinding (this is why std::uncaught_exceptions() was introduced).