Re: Synchronization Objects questions
- From: "Jürgen Devlieghere" <jdv_ommit_all_this@xxxxxxxxxxx>
- Date: Wed, 4 Jan 2006 16:22:51 +0100
The code in the said article contains indeed multiple flaws.
I also relied on it for implementing a read/write lock, and had to conclude
the code is not safe. A reader and a writer can get simultaneously access,
so not really what you want :-)
The problem is exactly what you describe: The interlocked increment /
decrement is not atomicly together with the Set or Reset of the event, so
another thread can also do a decrement before the event is changed.
So, also the reader and writer lock implementation is flawed.
I found a post from Peter Brian Clements suggesting a solution, but it
introduces another problem.
He moves the resetting upwards, and sets it afterwards again if needed. But
with 2 threads that leave, there can be a context switch when they have
passed the decrement, so the last one can set the event 'back', and
destroying the effect of the so-said last thread.
There is however a solution to this, by putting the releasing of a reader in
a critical section.
So, the original MSDN code was like this:
void CRWLock::Release(int i)
{
if (i == WRITER)
{
SetEvent(hMutex);
ReleaseMutex(hWriterMutex);
}
else
if (InterlockedDecrement(&iCounter) < 0)
{
// A context switch at this point will allow other reader
// thread to sneak into the lock. The first such thread will
// block waiting for the global synchronization object, but
// the others sneak past because the reader synchronization
// object is still set.
ResetEvent(hReaderEvent);
SetEvent(hMutex);
};
};
The modified solution becomes:
void CRWLock::Release(int i)
{
if (i == WRITER)
{
SetEvent(hMutex);
ReleaseMutex(hWriterMutex);
}
else
{
EnterCriticalSection(&csReaderReleasers);
ResetEvent(hReaderEvent);
if (InterlockedDecrement(&iCounter) < 0)
{
SetEvent(hMutex);
}
else
{
SetEvent(hReaderEvent);
};
LeaveCriticalSection(&csReaderReleasers);
};
};
The WFMO code seems rather similar to me, so I guess the solution is also
simular.
Jürgen
.
- Prev by Date: Dll for Hook the API OpenProcess
- Next by Date: Re: Help, Deleting Update Files
- Previous by thread: Dll for Hook the API OpenProcess
- Next by thread: Re: HOWTO Make a Proxy DLL for ADVAPI32.DLL and use it in a EXE
- Index(es):
Relevant Pages
|
Loading