Re: Synchronization Objects questions



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


.



Relevant Pages

  • Re: FLOCK/FWRITE/FUNLOCK to Message File Question
    ... I've been using message files with Cobol programs (1 writer and reader, ... and have never needed to lock them before doing the write. ... I have an app that writes to a message file thus: ...
    (comp.sys.hp.mpe)
  • Re: Can semaphore operations replace mutex+cond var?
    ... If the intent was that this let in only a single writer, ... when either of them releases the lock, the other one will be running ... Block on reader condvar while writercount>0, releasing sync mutex. ...
    (comp.programming.threads)
  • ReadersWritersLock in an unmanaged C++ program.
    ... I need to use some kind of lock (semaphore, Mutex, or any other ... The threads will have either the "Reader" role or the "Writer" role. ... When the first Writer thread is pending or working, ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Thread Pre-Emption Question . . .
    ... implementation to add promotion of read lock to write lock. ... (I said, it's a tricky question). ... writer lock without releasing reader in between. ...
    (microsoft.public.win32.programmer.kernel)
  • Re: [PATCH 3/3] ring-buffer: add design document
    ... This adds the design document for the ring buffer and also ... +head - where new reads happen in the ring buffer. ... +producer - the task that writes into the ring buffer (same as writer) ... +reader - same as consumer. ...
    (Linux-Kernel)

Loading