We've known for ages that it's not portable to do: __gthread_mutex_t tmp = __GTHREAD_MUTEX_INIT; _M_mutex = __tmp;
As PR 53270 shows, the copy assignment now actually fails in C++11 mode on platforms using LinuxThreads, because the mutex has a volatile member so in C++11 mode the copy assignment operator is deleted. This patch changes <ext/concurrence.h> to use a brace-or-equals-initializer for the mutexes and condition variable in C++11 mode, allowing hppa-linux to bootstrap again and avoiding the non-portable construct everywhere (this is already the approach we take for std::mutex etc. in <mutex>). It also makes the same change to the mutex used in <ext/rope> and fixes a resource leak in that header by ensuring the mutex is destroyed when it was initialized by __gthread_mutex_init_function. PR libstdc++/53270 * include/ext/concurrence.h (__mutex, __recursive_mutex, __cond): Use NSDMI in C++11 mode. * include/ext/rope (_Refcount_Base): Likewise. Destroy mutex in destructor when initialized by function. Tested x86_64-linux, powerpc64-linux, hppa-linux and x86_64-netbsd (on the 4.7 branch instead, as netbsd doesn't bootstrap at the moment.) Committed to trunk. For 4.6.4 and 4.7.2 I plan to make a less intrusive change, #undef'ing the __GTHREAD_MUTEX_INIT, _GTHREAD_RECURSIVE_MUTEX_INIT and __GTHREAD_COND_INIT macros on hppa-linux in C++11 mode, so that the init functions are used instead. This fixes the bootstrap regression on hppa-linux without affecting other targets.
commit 62d49cd435f56bc7c433b40bdec010a5e037712b Author: Jonathan Wakely <jwakely....@gmail.com> Date: Sat Jun 9 13:10:13 2012 +0100 PR libstdc++/53270 * include/ext/concurrence.h (__mutex, __recursive_mutex, __cond): Use NSDMI in C++11 mode. * include/ext/rope (_Refcount_Base): Likewise. Destroy mutex in destructor when initialized by function. diff --git a/libstdc++-v3/include/ext/concurrence.h b/libstdc++-v3/include/ext/concurrence.h index fc8f63f..22c433b 100644 --- a/libstdc++-v3/include/ext/concurrence.h +++ b/libstdc++-v3/include/ext/concurrence.h @@ -143,7 +143,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class __mutex { private: +#if __GTHREADS && defined __GTHREAD_MUTEX_INIT \ + && defined __GXX_EXPERIMENTAL_CXX0X__ + __gthread_mutex_t _M_mutex = __GTHREAD_MUTEX_INIT; +#else __gthread_mutex_t _M_mutex; +#endif __mutex(const __mutex&); __mutex& operator=(const __mutex&); @@ -155,8 +160,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__gthread_active_p()) { #if defined __GTHREAD_MUTEX_INIT +# ifndef __GXX_EXPERIMENTAL_CXX0X__ __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; _M_mutex = __tmp; +# endif #else __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex); #endif @@ -201,7 +208,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class __recursive_mutex { private: +#if __GTHREADS && defined __GTHREAD_RECURSIVE_MUTEX_INIT \ + && defined __GXX_EXPERIMENTAL_CXX0X__ + __gthread_recursive_mutex_t _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT; +#else __gthread_recursive_mutex_t _M_mutex; +#endif __recursive_mutex(const __recursive_mutex&); __recursive_mutex& operator=(const __recursive_mutex&); @@ -213,8 +225,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__gthread_active_p()) { #if defined __GTHREAD_RECURSIVE_MUTEX_INIT +# ifndef __GXX_EXPERIMENTAL_CXX0X__ __gthread_recursive_mutex_t __tmp = __GTHREAD_RECURSIVE_MUTEX_INIT; _M_mutex = __tmp; +# endif #else __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex); #endif @@ -319,7 +333,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION class __cond { private: +#if __GTHREADS && defined __GTHREAD_COND_INIT \ + && defined __GXX_EXPERIMENTAL_CXX0X__ + __gthread_cond_t _M_cond = __GTHREAD_COND_INIT; +#else __gthread_cond_t _M_cond; +#endif __cond(const __cond&); __cond& operator=(const __cond&); @@ -331,8 +350,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__gthread_active_p()) { #if defined __GTHREAD_COND_INIT +# ifndef __GXX_EXPERIMENTAL_CXX0X__ __gthread_cond_t __tmp = __GTHREAD_COND_INIT; _M_cond = __tmp; +# endif #else __GTHREAD_COND_INIT_FUNCTION(&_M_cond); #endif diff --git a/libstdc++-v3/include/ext/rope b/libstdc++-v3/include/ext/rope index 5e82811..15cb423 100644 --- a/libstdc++-v3/include/ext/rope +++ b/libstdc++-v3/include/ext/rope @@ -458,13 +458,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION volatile _RC_t _M_ref_count; // Constructor +#if defined __GTHREAD_MUTEX_INIT && defined __GXX_EXPERIMENTAL_CXX0X__ + __gthread_mutex_t _M_ref_count_lock = __GTHREAD_MUTEX_INIT; +#else __gthread_mutex_t _M_ref_count_lock; +#endif _Refcount_Base(_RC_t __n) : _M_ref_count(__n), _M_ref_count_lock() { #ifdef __GTHREAD_MUTEX_INIT +# ifndef __GXX_EXPERIMENTAL_CXX0X__ __gthread_mutex_t __tmp = __GTHREAD_MUTEX_INIT; _M_ref_count_lock = __tmp; +# endif #elif defined(__GTHREAD_MUTEX_INIT_FUNCTION) __GTHREAD_MUTEX_INIT_FUNCTION (&_M_ref_count_lock); #else @@ -472,6 +478,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif } +#ifndef __GTHREAD_MUTEX_INIT + ~_Refcount_Base() + { __gthread_mutex_destroy(&_M_ref_count_lock); } +#endif + void _M_incr() {