* initialise fwritelocked and freadercount in the TMREWS constructor using

atomic operations so that in case it's created while multiple threads are
    already running, all threads are guaranteed to see this initialisation
  * some minor changes to the comments of TMREWS

git-svn-id: trunk@15074 -
This commit is contained in:
Jonas Maebe 2010-03-27 12:44:51 +00:00
parent 3f2d66b188
commit d5f415b047

View File

@ -50,8 +50,10 @@ begin
System.InitCriticalSection(fwritelock);
fwaitingwriterlock:=RTLEventCreate;
RTLEventResetEvent(fwaitingwriterlock);
fwritelocked:=0;
freadercount:=0;
{ make sure all threads see the initialisation of fwritelock and
freadercount (we only use atomic operation further on as well) }
System.InterlockedExchange(freadercount,0);
System.InterlockedExchange(fwritelocked,0);
freaderqueue:=BasicEventCreate(nil,true,false,'');
end;
@ -69,15 +71,15 @@ function TMultiReadExclusiveWriteSynchronizer.Beginwrite : boolean;
begin
{ wait for any other writers that may be in progress }
System.EnterCriticalSection(fwritelock);
{ it is possible that we earlier on missed waiting on the
{ it is possible that earlier on we missed waiting on the
fwaitingwriterlock and that it's still set (must be done
after aquiring the fwritelock, because otherwise one
after acquiring the fwritelock, because otherwise one
writer could reset the fwaitingwriterlock of another one
that's about to wait on it) }
RTLeventResetEvent(fwaitingwriterlock);
{ new readers have to block from now on; writers get priority to avoid
writer starvation (since they have to compete with potentially many
concurrent readers) }
concurrent readers and other writers) }
BasicEventResetEvent(freaderqueue);
{ for quick checking by candidate-readers -- use interlockedincrement/
decrement instead of setting 1/0, because a single thread can
@ -154,8 +156,8 @@ end;
procedure TMultiReadExclusiveWriteSynchronizer.Endread;
begin
{ If no more readers, wake writer in the ready-queue if any. Since a writer
always first atomically sets the fwritelocked and then atomically checks
the freadercount, first modifying freadercount and then checking fwritelock
always first atomically sets fwritelocked and then atomically checks the
freadercount, first modifying freadercount and then checking fwritelock
ensures that we cannot miss one of the events regardless of execution
order. }
if (System.InterlockedDecrement(freadercount)=0) and