|
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