Jelajahi Sumber

* 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 tahun lalu
induk
melakukan
d5f415b047
1 mengubah file dengan 9 tambahan dan 7 penghapusan
  1. 9 7
      rtl/objpas/sysutils/sysuthrd.inc

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

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