Browse Source

* 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 -

Jonas Maebe 15 years ago
parent
commit
d5f415b047
1 changed files with 9 additions and 7 deletions
  1. 9 7
      rtl/objpas/sysutils/sysuthrd.inc

+ 9 - 7
rtl/objpas/sysutils/sysuthrd.inc

@@ -50,8 +50,10 @@ begin
   System.InitCriticalSection(fwritelock);
   System.InitCriticalSection(fwritelock);
   fwaitingwriterlock:=RTLEventCreate;
   fwaitingwriterlock:=RTLEventCreate;
   RTLEventResetEvent(fwaitingwriterlock);
   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,'');
   freaderqueue:=BasicEventCreate(nil,true,false,'');
 end;
 end;
 
 
@@ -69,15 +71,15 @@ function  TMultiReadExclusiveWriteSynchronizer.Beginwrite : boolean;
 begin
 begin
   { wait for any other writers that may be in progress }
   { wait for any other writers that may be in progress }
   System.EnterCriticalSection(fwritelock);
   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
     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
     writer could reset the fwaitingwriterlock of another one
     that's about to wait on it) }
     that's about to wait on it) }
   RTLeventResetEvent(fwaitingwriterlock);
   RTLeventResetEvent(fwaitingwriterlock);
   { new readers have to block from now on; writers get priority to avoid
   { new readers have to block from now on; writers get priority to avoid
     writer starvation (since they have to compete with potentially many
     writer starvation (since they have to compete with potentially many
-    concurrent readers) }
+    concurrent readers and other writers) }
   BasicEventResetEvent(freaderqueue);
   BasicEventResetEvent(freaderqueue);
   { for quick checking by candidate-readers -- use interlockedincrement/
   { for quick checking by candidate-readers -- use interlockedincrement/
     decrement instead of setting 1/0, because a single thread can
     decrement instead of setting 1/0, because a single thread can
@@ -154,8 +156,8 @@ end;
 procedure  TMultiReadExclusiveWriteSynchronizer.Endread;
 procedure  TMultiReadExclusiveWriteSynchronizer.Endread;
 begin
 begin
   { If no more readers, wake writer in the ready-queue if any. Since a writer
   { 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
     ensures that we cannot miss one of the events regardless of execution
     order. }
     order. }
   if (System.InterlockedDecrement(freadercount)=0) and
   if (System.InterlockedDecrement(freadercount)=0) and