mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 15:49:26 +02:00
* 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:
parent
3f2d66b188
commit
d5f415b047
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user