Refactored the ReentrantMutex support so that it utilises the underling thread implementation for recusive mutex support.

This commit is contained in:
Robert Osfield 2010-02-18 20:14:41 +00:00
parent ab66740fb0
commit 787daeeb93
5 changed files with 33 additions and 100 deletions

View File

@ -34,16 +34,26 @@ class OPENTHREAD_EXPORT_DIRECTIVE Mutex {
public: public:
enum MutexType
{
MUTEX_NORMAL,
MUTEX_RECURSIVE
};
/** /**
* Constructor * Constructor
*/ */
Mutex(); Mutex(MutexType type=MUTEX_NORMAL);
/** /**
* Destructor * Destructor
*/ */
virtual ~Mutex(); virtual ~Mutex();
MutexType getMutexType() const { return _mutexType; }
/** /**
* Lock the mutex * Lock the mutex
* *
@ -81,6 +91,7 @@ private:
* Implementation-specific private data. * Implementation-specific private data.
*/ */
void *_prvData; void *_prvData;
MutexType _mutexType;
}; };

View File

@ -25,98 +25,7 @@ class ReentrantMutex : public OpenThreads::Mutex
public: public:
ReentrantMutex(): ReentrantMutex():
_threadHoldingMutex(0), Mutex(MUTEX_RECURSIVE) {}
_lockCount(0) {}
virtual ~ReentrantMutex() {}
virtual int lock()
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
{
++_lockCount;
return 0;
}
}
int result = Mutex::lock();
if (result==0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
_threadHoldingMutex = OpenThreads::Thread::CurrentThread();
_lockCount = 1;
}
return result;
}
virtual int unlock()
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
#if 0
if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
{
--_lockCount;
if (_lockCount<=0)
{
_threadHoldingMutex = 0;
return Mutex::unlock();
}
}
else
{
osg::notify(osg::NOTICE)<<"Error: ReentrantMutex::unlock() - unlocking from the wrong thread."<<std::endl;
}
#else
if (_lockCount>0)
{
--_lockCount;
if (_lockCount<=0)
{
_threadHoldingMutex = 0;
return Mutex::unlock();
}
}
#endif
return 0;
}
virtual int trylock()
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
{
++_lockCount;
return 0;
}
}
int result = Mutex::trylock();
if (result==0)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_lockCountMutex);
_threadHoldingMutex = OpenThreads::Thread::CurrentThread();
_lockCount = 1;
}
return result;
}
private:
ReentrantMutex(const ReentrantMutex&):OpenThreads::Mutex() {}
ReentrantMutex& operator =(const ReentrantMutex&) { return *(this); }
OpenThreads::Thread* _threadHoldingMutex;
OpenThreads::Mutex _lockCountMutex;
unsigned int _lockCount;
}; };

View File

@ -30,17 +30,25 @@ using namespace OpenThreads;
// //
// Use: public. // Use: public.
// //
Mutex::Mutex() { Mutex::Mutex(MutexType type):
_mutexType(type)
{
pthread_mutexattr_t mutex_attr; pthread_mutexattr_t mutex_attr;
pthread_mutexattr_init( &mutex_attr ); pthread_mutexattr_init( &mutex_attr );
PThreadMutexPrivateData *pd = new PThreadMutexPrivateData(); PThreadMutexPrivateData *pd = new PThreadMutexPrivateData();
#ifndef __linux__ // (not available until NPTL) [
pthread_mutexattr_settype( &mutex_attr, PTHREAD_MUTEX_ERRORCHECK );
#endif // ] __linux__
if (type==MUTEX_RECURSIVE)
{
pthread_mutexattr_settype( &mutex_attr, PTHREAD_MUTEX_RECURSIVE );
}
else
{
#ifndef __linux__ // (not available until NPTL) [
pthread_mutexattr_settype( &mutex_attr, PTHREAD_MUTEX_ERRORCHECK );
#endif // ] __linux__
}
#ifdef ALLOW_PRIORITY_SCHEDULING // [ #ifdef ALLOW_PRIORITY_SCHEDULING // [
#ifdef __sun // [ #ifdef __sun // [

View File

@ -34,7 +34,9 @@ using namespace OpenThreads;
// //
// Use: public. // Use: public.
// //
Mutex::Mutex() { Mutex::Mutex(MutexType type):
_mutexType(type)
{
SprocMutexPrivateData *pd = new SprocMutexPrivateData(); SprocMutexPrivateData *pd = new SprocMutexPrivateData();

View File

@ -81,7 +81,10 @@ static void _S_nsec_sleep(int __log_nsec) {
// //
// Use: public. // Use: public.
// //
Mutex::Mutex() { Mutex::Mutex(MutexType type):
_mutexType(type)
)
{
Win32MutexPrivateData *pd = new Win32MutexPrivateData(); Win32MutexPrivateData *pd = new Win32MutexPrivateData();
_prvData = static_cast<void *>(pd); _prvData = static_cast<void *>(pd);
} }