Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r62720 - trunk/boost/thread/pthread
From: anthony_at_[hidden]
Date: 2010-06-10 04:10:29


Author: anthonyw
Date: 2010-06-10 04:10:26 EDT (Thu, 10 Jun 2010)
New Revision: 62720
URL: http://svn.boost.org/trac/boost/changeset/62720

Log:
Emulate recursive mutex if pthread_mutexattr_settype not
available. Fix for issue #2955

Text files modified:
   trunk/boost/thread/pthread/recursive_mutex.hpp | 86 +++++++++++++++++++++++++++++++++++++--
   1 files changed, 80 insertions(+), 6 deletions(-)

Modified: trunk/boost/thread/pthread/recursive_mutex.hpp
==============================================================================
--- trunk/boost/thread/pthread/recursive_mutex.hpp (original)
+++ trunk/boost/thread/pthread/recursive_mutex.hpp 2010-06-10 04:10:26 EDT (Thu, 10 Jun 2010)
@@ -26,6 +26,10 @@
 #endif
 #endif
 
+#if defined(BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE) && defined(BOOST_PTHREAD_HAS_TIMEDLOCK)
+#define BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
+#endif
+
 #include <boost/config/abi_prefix.hpp>
 
 namespace boost
@@ -36,9 +40,16 @@
         recursive_mutex(recursive_mutex const&);
         recursive_mutex& operator=(recursive_mutex const&);
         pthread_mutex_t m;
+#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
+ pthread_cond_t cond;
+ bool is_locked;
+ pthread_t owner;
+ unsigned count;
+#endif
     public:
         recursive_mutex()
         {
+#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
             pthread_mutexattr_t attr;
             
             int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -55,15 +66,35 @@
             int const res=pthread_mutex_init(&m,&attr);
             if(res)
             {
+ BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
                 boost::throw_exception(thread_resource_error());
             }
             BOOST_VERIFY(!pthread_mutexattr_destroy(&attr));
+#else
+ int const res=pthread_mutex_init(&m,NULL);
+ if(res)
+ {
+ boost::throw_exception(thread_resource_error());
+ }
+ int const res2=pthread_cond_init(&cond,NULL);
+ if(res2)
+ {
+ BOOST_VERIFY(!pthread_mutex_destroy(&m));
+ boost::throw_exception(thread_resource_error());
+ }
+ is_locked=false;
+ count=0;
+#endif
         }
         ~recursive_mutex()
         {
             BOOST_VERIFY(!pthread_mutex_destroy(&m));
+#ifndef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
+ BOOST_VERIFY(!pthread_cond_destroy(&cond));
+#endif
         }
-
+
+#ifdef BOOST_PTHREAD_HAS_MUTEXATTR_SETTYPE
         void lock()
         {
             BOOST_VERIFY(!pthread_mutex_lock(&m));
@@ -80,13 +111,56 @@
             BOOST_ASSERT(!res || res==EBUSY);
             return !res;
         }
-
         typedef pthread_mutex_t* native_handle_type;
         native_handle_type native_handle()
         {
             return &m;
         }
 
+#else
+ void lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && pthread_equal(owner,pthread_self()))
+ {
+ ++count;
+ return;
+ }
+
+ while(is_locked)
+ {
+ BOOST_VERIFY(!pthread_cond_wait(&cond,&m));
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ }
+
+ void unlock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(!--count)
+ {
+ is_locked=false;
+ }
+ BOOST_VERIFY(!pthread_cond_signal(&cond));
+ }
+
+ bool try_lock()
+ {
+ boost::pthread::pthread_mutex_scoped_lock const local_lock(&m);
+ if(is_locked && !pthread_equal(owner,pthread_self()))
+ {
+ return false;
+ }
+ is_locked=true;
+ ++count;
+ owner=pthread_self();
+ return true;
+ }
+
+#endif
+
         typedef unique_lock<recursive_mutex> scoped_lock;
         typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
@@ -100,7 +174,7 @@
         recursive_timed_mutex& operator=(recursive_timed_mutex const&);
     private:
         pthread_mutex_t m;
-#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
         pthread_cond_t cond;
         bool is_locked;
         pthread_t owner;
@@ -109,7 +183,7 @@
     public:
         recursive_timed_mutex()
         {
-#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
             pthread_mutexattr_t attr;
             
             int const init_attr_res=pthread_mutexattr_init(&attr);
@@ -149,7 +223,7 @@
         ~recursive_timed_mutex()
         {
             BOOST_VERIFY(!pthread_mutex_destroy(&m));
-#ifndef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifndef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
             BOOST_VERIFY(!pthread_cond_destroy(&cond));
 #endif
         }
@@ -160,7 +234,7 @@
             return timed_lock(get_system_time()+relative_time);
         }
 
-#ifdef BOOST_PTHREAD_HAS_TIMEDLOCK
+#ifdef BOOST_USE_PTHREAD_RECURSIVE_TIMEDLOCK
         void lock()
         {
             BOOST_VERIFY(!pthread_mutex_lock(&m));


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk