Browse Source

* WebAssembly threads: fixed race condition LockMutex in the check where Locked
is 1, but Owner still holds the current thread id, even though another thread
has just acquired a lock, but still haven't updated the owner thread ID. We
avoid this problem by setting Owner to nil before unlocking the mutex. And in
InitMutex/DoneMutex, we store the creator thread ID in a different field -
Creator, instead of Owner.

Nikolay Nikolov 1 year ago
parent
commit
41ead20bfb
2 changed files with 5 additions and 3 deletions
  1. 2 1
      rtl/wasi/sysosh.inc
  2. 3 2
      rtl/wasi/wasmmutex.inc

+ 2 - 1
rtl/wasi/sysosh.inc

@@ -27,6 +27,7 @@ type
     Count: LongInt; // Number of times locked.
     Waiters : LongInt; // Number of waiters
     Kind : LongInt; // Kind of mutex, Equals Ord(TMutexKind)
-    Owner : TThreadID;  // Owner thread
+    Owner : TThreadID;  // Owner thread (who holds the lock)
+    Creator : TThreadID;  // Creator thread
     Destroying : Boolean; // Set when notifying that we're destroying the mutex.
   end;

+ 3 - 2
rtl/wasi/wasmmutex.inc

@@ -20,7 +20,7 @@ begin
   FillChar(M,SizeOf(TWasmMutex),0);
   if aOwner=Nil then
     aOwner:=GetSelfThread;
-  M.Owner:=aOwner;
+  M.Creator:=aOwner;
   M.Kind:=Ord(aKind);
 end;
 
@@ -30,7 +30,7 @@ Var
   a : LongInt;
 
 begin
-  if (M.Locked>0) and (M.Owner=GetSelfThread) then
+  if (M.Locked>0) and (M.Creator=GetSelfThread) then
     begin
     M.Destroying:=True;
     a:=fpc_wasm32_memory_atomic_notify(@M.Locked,MaxThreadSignal);
@@ -190,6 +190,7 @@ begin
       InterLockedDecrement(M.Count);
     if (M.Count=0) then
       begin
+        M.Owner:=nil;
         M.Locked:=0;
         a:=fpc_wasm32_memory_atomic_notify(@M.Locked,1);
       end;