c++multithreadingmutexresource-management

Why does condition_variable_any needs a mutex managed by a shared_ptr?


The implementation of std::conditional_variable_any needs (in gcc and clang) a std::shared_ptr.

Inside the wait methods, the lifetime of the mutex will be extended to the local scope.

template<typename _Lock>
  void
  wait(_Lock& __lock)
  {
shared_ptr<mutex> __mutex = _M_mutex; // <-- Extend lifetime of mutex.
unique_lock<mutex> __my_lock(*__mutex);
_Unlock<_Lock> __unlock(__lock);
// *__mutex must be unlocked before re-locking __lock so move
// ownership of *__mutex lock to an object with shorter lifetime.
unique_lock<mutex> __my_lock2(std::move(__my_lock));
_M_cond.wait(__my_lock2);
  }

I wonder, why we need this here? As long as the conditional_variable_any object lives, the mutex exist. Wouldn't a std::mutex be enough?


Solution

  • The code was added in this bug report: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54352

    Here is the explanation: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54185

    The c11 standard (draft 3337, paragraph 30.5.1.5) states that condition_variable may be destructed even if not all wait() calls have returned, so long as all of those calls are blocking on the associated lock rather than on *this.

    So the lifetime must be extended to prevent destructing the mutex while it is still in use.