I have just reviewed the code, but as yet don't see a problem, but if there is then I'd certainly like to track it down and fix it. Comments indispersed below.
On 9/15/06,
Schmidt, Richard, SDGE1 <[EMAIL PROTECTED]> wrote:
If it unlocks it then _lockCount will be decrement, if its the last unlock then _lockCount will go to 0.0, and finally the lock will actually be released.
Two senario's, the previous unlock left _lockCount > 0 i,e, 1 , in which case the _lockCount will be incremented to one more i.e. 2.
The other case is the that previous unlock left _lockCount==0 and actually unlocked the mutex, in this case the if statement in ReentrantMutext::lock():
if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
{
++_lockCount;
return 0;
}
else ...
Would not pass, and the the second block:
else
{
int result = Mutex::lock();
if (result==0)
{
_threadHoldingMutex = OpenThreads::Thread::CurrentThread();
_lockCount = 1;
}
return result;
}
Would be executed.
No this shoudln't happen, the second thread will hit the second code block but then sit on the Mutex::lock() till the first thread does sufficient unlock() calls to unlock it.
Hi all,
I am not quite sure if osgDB/Reentrant Mutex is threadsafe (just got
into Multithreading). Lets make a little example. Consider two Threads:
Thread one and Thread two.
Now lets make this sequence of operations:
* Normal Program Flow everything runs fine so far.
* Thread one just unlocked the Reentrant Mutex, so "_threadHoldingMutex"
is Thread one.
If it unlocks it then _lockCount will be decrement, if its the last unlock then _lockCount will go to 0.0, and finally the lock will actually be released.
* Now Thread one tries to aquire the lock again by calling
"ReentrantMutex::lock()" and passes
"_threadHoldingMutex==OpenThreads::Thread::CurrentThread()"
Two senario's, the previous unlock left _lockCount > 0 i,e, 1 , in which case the _lockCount will be incremented to one more i.e. 2.
The other case is the that previous unlock left _lockCount==0 and actually unlocked the mutex, in this case the if statement in ReentrantMutext::lock():
if (_threadHoldingMutex==OpenThreads::Thread::CurrentThread() && _lockCount>0)
{
++_lockCount;
return 0;
}
else ...
Would not pass, and the the second block:
else
{
int result = Mutex::lock();
if (result==0)
{
_threadHoldingMutex = OpenThreads::Thread::CurrentThread();
_lockCount = 1;
}
return result;
}
Would be executed.
* Now Thread two gets some time calling "ReentrantMutex::lock()" and
since _threadHoldingMutex==OpenThreads::Thread::CurrentThread() is not
true for this one it is going to lock the OpenThreads::Mutex and setting
the "_lockCount" to "1".
No this shoudln't happen, the second thread will hit the second code block but then sit on the Mutex::lock() till the first thread does sufficient unlock() calls to unlock it.
* Now back to the other Thread, which is passes "_lockCount > 0" now and
gets the ReentrantLock as well.
Conculsion: Both Threads aquire the lock.
Maybe solution: Setting "_threadHoldingMutex" to "0" when unlocking the
Thread.
I "think" the code is ok, but perhaps I've missed something subtle, threading can be rather awkward subject, sometimes you have to bang you head against a wall for a while before the actual maner of what happens becomes clear.
Robert.
_______________________________________________ osg-users mailing list [email protected] http://openscenegraph.net/mailman/listinfo/osg-users http://www.openscenegraph.org/
