Refactored the ReentrantMutex support so that it utilises the underling thread implementation for recusive mutex support.
This commit is contained in:
parent
ab66740fb0
commit
787daeeb93
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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 // [
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user