Patchwork [v3] use NSDMI in C++11 mutex types

login
register
mail settings
Submitter Jonathan Wakely
Date Oct. 24, 2011, 11:26 p.m.
Message ID <CAH6eHdTKACb1ZQKzCK0Or1qk4GZExp-HzGskuqq26p6Km0pV0g@mail.gmail.com>
Download mbox | patch
Permalink /patch/121454/
State New
Headers show

Comments

Jonathan Wakely - Oct. 24, 2011, 11:26 p.m.
PR libstdc++/49894
        * include/std/mutex (__mutex_base,__recursive_mutex_base): Define new
        base classes to manage construction/destruction of native mutexes,
        using NSDMI when INIT macros are defined.
        (mutex,recursive_mutex,timed_mutex,recursive_timed_mutex): Derive from
        new base classes.
        * include/std/condition_variable (condition_variable): Use NSDMI when
        INIT macro is defined. Use noexcept.
        * src/condition_variable.cc (condition_variable): Explicitly-default
        constructor/destructor when using NSDMI. Use noexcept.
        (condition_variable_any): Likewise.

Tested x86_64-linux, committed to trunk.

Patch

Index: include/std/mutex
===================================================================
--- include/std/mutex	(revision 180329)
+++ include/std/mutex	(working copy)
@@ -52,6 +52,94 @@ 
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+  // Common base class for std::mutex and std::timed_mutex
+  class __mutex_base
+  {
+  protected:
+    typedef __gthread_mutex_t			__native_type;
+
+#ifdef __GTHREAD_MUTEX_INIT
+    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
+
+    constexpr __mutex_base() noexcept = default;
+#else
+    __native_type  _M_mutex;
+
+    __mutex_base() noexcept
+    {
+      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
+      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
+    }
+
+    ~__mutex_base() { __gthread_mutex_destroy(&_M_mutex); }
+#endif
+
+    __mutex_base(const __mutex_base&) = delete;
+    __mutex_base& operator=(const __mutex_base&) = delete;
+  };
+
+  // Common base class for std::recursive_mutex and std::timed_recursive_mutex
+  class __recursive_mutex_base
+  {
+  protected:
+    typedef __gthread_recursive_mutex_t		__native_type;
+
+    __recursive_mutex_base(const __recursive_mutex_base&) = delete;
+    __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete;
+
+#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
+    __native_type  _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
+
+    __recursive_mutex_base() = default;
+#else
+    __native_type  _M_mutex;
+
+    __recursive_mutex_base()
+    {
+      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
+      __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
+    }
+
+    ~__recursive_mutex_base()
+    { _S_destroy(&_M_mutex); }
+
+  private:
+    // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy
+    // so we need to obtain a __gthread_mutex_t to destroy
+
+    // matches when there's only one mutex type
+    template<typename _Rm>
+      static
+      typename enable_if<is_same<_Rm, __gthread_mutex_t>::value, void>::type
+      _S_destroy(_Rm* __mx)
+      { __gthread_mutex_destroy(__mx); }
+
+    // matches a recursive mutex with a member 'actual'
+    template<typename _Rm>
+      static typename enable_if<sizeof(&_Rm::actual), void>::type
+      _S_destroy(_Rm* __mx)
+      { __gthread_mutex_destroy(&__mx->actual); }
+
+    // matches a gthr-win32.h recursive mutex
+    template<typename _Rm>
+      static typename enable_if<sizeof(&_Rm::sema), void>::type
+      _S_destroy(_Rm* __mx)
+      {
+        __gthread_mutex_t __tmp;
+        _S_destroy_win32(&__tmp, __mx);
+      }
+
+    template<typename _Mx, typename _Rm>
+      static void
+      _S_destroy_win32(_Mx* __mx, _Rm const* __rmx)
+      {
+        __mx->counter = __rmx->counter;
+        __mx->sema = __rmx->sema;
+        __gthread_mutex_destroy(__mx);
+      }
+#endif
+  };
+
   /**
    * @defgroup mutexes Mutexes
    * @ingroup concurrency
@@ -61,25 +149,16 @@ 
    */
 
   /// mutex
-  class mutex
+  class mutex : private __mutex_base
   {
-    typedef __gthread_mutex_t			__native_type;
-    __native_type  _M_mutex;
-
   public:
     typedef __native_type* 			native_handle_type;
 
 #ifdef __GTHREAD_MUTEX_INIT
-    constexpr mutex() noexcept : _M_mutex(__GTHREAD_MUTEX_INIT) { }
-#else
-    mutex() noexcept
-    {
-      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
-      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
-    }
-
-    ~mutex() { __gthread_mutex_destroy(&_M_mutex); }
+    constexpr
 #endif
+    mutex() noexcept = default;
+    ~mutex() = default;
 
     mutex(const mutex&) = delete;
     mutex& operator=(const mutex&) = delete;
@@ -113,67 +192,15 @@ 
     { return &_M_mutex; }
   };
 
-#ifndef __GTHREAD_RECURSIVE_MUTEX_INIT
-  // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy
-  // so we need to obtain a __gthread_mutex_t to destroy
-  class __destroy_recursive_mutex
-  {
-    template<typename _Mx, typename _Rm>
-      static void
-      _S_destroy_win32(_Mx* __mx, _Rm const* __rmx)
-      {
-        __mx->counter = __rmx->counter;
-        __mx->sema = __rmx->sema;
-        __gthread_mutex_destroy(__mx);
-      }
-
-  public:
-    // matches a gthr-win32.h recursive mutex
-    template<typename _Rm>
-      static typename enable_if<sizeof(&_Rm::sema), void>::type
-      _S_destroy(_Rm* __mx)
-      {
-        __gthread_mutex_t __tmp;
-        _S_destroy_win32(&__tmp, __mx);
-      }
-
-    // matches a recursive mutex with a member 'actual'
-    template<typename _Rm>
-      static typename enable_if<sizeof(&_Rm::actual), void>::type
-      _S_destroy(_Rm* __mx)
-      { __gthread_mutex_destroy(&__mx->actual); }
-
-    // matches when there's only one mutex type
-    template<typename _Rm>
-      static
-      typename enable_if<is_same<_Rm, __gthread_mutex_t>::value, void>::type
-      _S_destroy(_Rm* __mx)
-      { __gthread_mutex_destroy(__mx); }
-  };
-#endif
-
   /// recursive_mutex
-  class recursive_mutex
+  class recursive_mutex : private __recursive_mutex_base
   {
-    typedef __gthread_recursive_mutex_t		__native_type;
-    __native_type  _M_mutex;
-
   public:
     typedef __native_type* 			native_handle_type;
 
-#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
-    recursive_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { }
-#else
-    recursive_mutex()
-    {
-      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
-      __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
-    }
+    recursive_mutex() = default;
+    ~recursive_mutex() = default;
 
-    ~recursive_mutex()
-    { __destroy_recursive_mutex::_S_destroy(&_M_mutex); }
-#endif
-
     recursive_mutex(const recursive_mutex&) = delete;
     recursive_mutex& operator=(const recursive_mutex&) = delete;
 
@@ -208,32 +235,20 @@ 
 
 #if _GTHREAD_USE_MUTEX_TIMEDLOCK
   /// timed_mutex
-  class timed_mutex
+  class timed_mutex : private __mutex_base
   {
-    typedef __gthread_mutex_t 		  	__native_type;
-
 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
     typedef chrono::steady_clock 	  	__clock_t;
 #else
     typedef chrono::high_resolution_clock 	__clock_t;
 #endif
 
-    __native_type  _M_mutex;
-
   public:
     typedef __native_type* 		  	native_handle_type;
 
-#ifdef __GTHREAD_MUTEX_INIT
-    timed_mutex() : _M_mutex(__GTHREAD_MUTEX_INIT) { }
-#else
-    timed_mutex()
-    {
-      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
-    }
+    timed_mutex() = default;
+    ~timed_mutex() = default;
 
-    ~timed_mutex() { __gthread_mutex_destroy(&_M_mutex); }
-#endif
-
     timed_mutex(const timed_mutex&) = delete;
     timed_mutex& operator=(const timed_mutex&) = delete;
 
@@ -313,34 +328,20 @@ 
   };
 
   /// recursive_timed_mutex
-  class recursive_timed_mutex
+  class recursive_timed_mutex : private __recursive_mutex_base
   {
-    typedef __gthread_recursive_mutex_t		__native_type;
-
 #ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
     typedef chrono::steady_clock 		__clock_t;
 #else
     typedef chrono::high_resolution_clock 	__clock_t;
 #endif
 
-    __native_type  _M_mutex;
-
   public:
     typedef __native_type* 			native_handle_type;
 
-#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
-    recursive_timed_mutex() : _M_mutex(__GTHREAD_RECURSIVE_MUTEX_INIT) { }
-#else
-    recursive_timed_mutex()
-    {
-      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
-      __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
-    }
+    recursive_timed_mutex() = default;
+    ~recursive_timed_mutex() = default;
 
-    ~recursive_timed_mutex()
-    { __destroy_recursive_mutex::_S_destroy(&_M_mutex); }
-#endif
-
     recursive_timed_mutex(const recursive_timed_mutex&) = delete;
     recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
 
Index: include/std/condition_variable
===================================================================
--- include/std/condition_variable	(revision 180329)
+++ include/std/condition_variable	(working copy)
@@ -60,22 +60,27 @@ 
   {
     typedef chrono::system_clock	__clock_t;
     typedef __gthread_cond_t		__native_type;
+
+#ifdef __GTHREAD_COND_INIT
+    __native_type			_M_cond = __GTHREAD_COND_INIT;
+#else
     __native_type			_M_cond;
+#endif
 
   public:
     typedef __native_type* 		native_handle_type;
 
-    condition_variable() throw ();
-    ~condition_variable() throw ();
+    condition_variable() noexcept;
+    ~condition_variable() noexcept;
 
     condition_variable(const condition_variable&) = delete;
     condition_variable& operator=(const condition_variable&) = delete;
 
     void
-    notify_one();
+    notify_one() noexcept;
 
     void
-    notify_all();
+    notify_all() noexcept;
 
     void
     wait(unique_lock<mutex>& __lock);
@@ -174,21 +179,21 @@ 
   public:
     typedef condition_variable::native_handle_type	native_handle_type;
 
-    condition_variable_any() throw ();
-    ~condition_variable_any() throw ();
+    condition_variable_any() noexcept;
+    ~condition_variable_any() noexcept;
 
     condition_variable_any(const condition_variable_any&) = delete;
     condition_variable_any& operator=(const condition_variable_any&) = delete;
 
     void
-    notify_one()
+    notify_one() noexcept
     {
       lock_guard<mutex> __lock(_M_mutex);
       _M_cond.notify_one();
     }
 
     void
-    notify_all()
+    notify_all() noexcept
     {
       lock_guard<mutex> __lock(_M_mutex);
       _M_cond.notify_all();
Index: src/condition_variable.cc
===================================================================
--- src/condition_variable.cc	(revision 180329)
+++ src/condition_variable.cc	(working copy)
@@ -30,25 +30,25 @@ 
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
-  condition_variable::condition_variable() throw ()
-  {
 #ifdef __GTHREAD_COND_INIT
-    __native_type __tmp = __GTHREAD_COND_INIT;
-    _M_cond = __tmp;
+  condition_variable::condition_variable() = default;
+  condition_variable::~condition_variable() = default;
 #else
+  condition_variable::condition_variable() noexcept
+  {
     int __e = __gthread_cond_init(&_M_cond, 0);
 
     if (__e)
       __throw_system_error(__e);
-#endif
   }
 
-  condition_variable::~condition_variable() throw ()
+  condition_variable::~condition_variable() noexcept
   {
     // XXX no thread blocked
     /* int __e = */ __gthread_cond_destroy(&_M_cond);
     // if __e == EBUSY then blocked
   }
+#endif
 
   void
   condition_variable::wait(unique_lock<mutex>& __lock)
@@ -60,7 +60,7 @@ 
   }
 
   void
-  condition_variable::notify_one()
+  condition_variable::notify_one() noexcept
   {
     int __e = __gthread_cond_signal(&_M_cond);
 
@@ -71,7 +71,7 @@ 
   }
 
   void
-  condition_variable::notify_all()
+  condition_variable::notify_all() noexcept
   {
     int __e = __gthread_cond_broadcast(&_M_cond);
 
@@ -81,11 +81,9 @@ 
       __throw_system_error(__e);
   }
 
-  condition_variable_any::condition_variable_any() throw ()
-  { }
+  condition_variable_any::condition_variable_any() noexcept = default;
 
-  condition_variable_any::~condition_variable_any() throw ()
-  { }
+  condition_variable_any::~condition_variable_any() noexcept = default;
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace