mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 22:59:21 +02:00
* 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.
This commit is contained in:
parent
692bd62359
commit
41ead20bfb
@ -27,6 +27,7 @@ type
|
|||||||
Count: LongInt; // Number of times locked.
|
Count: LongInt; // Number of times locked.
|
||||||
Waiters : LongInt; // Number of waiters
|
Waiters : LongInt; // Number of waiters
|
||||||
Kind : LongInt; // Kind of mutex, Equals Ord(TMutexKind)
|
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.
|
Destroying : Boolean; // Set when notifying that we're destroying the mutex.
|
||||||
end;
|
end;
|
||||||
|
@ -20,7 +20,7 @@ begin
|
|||||||
FillChar(M,SizeOf(TWasmMutex),0);
|
FillChar(M,SizeOf(TWasmMutex),0);
|
||||||
if aOwner=Nil then
|
if aOwner=Nil then
|
||||||
aOwner:=GetSelfThread;
|
aOwner:=GetSelfThread;
|
||||||
M.Owner:=aOwner;
|
M.Creator:=aOwner;
|
||||||
M.Kind:=Ord(aKind);
|
M.Kind:=Ord(aKind);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ Var
|
|||||||
a : LongInt;
|
a : LongInt;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (M.Locked>0) and (M.Owner=GetSelfThread) then
|
if (M.Locked>0) and (M.Creator=GetSelfThread) then
|
||||||
begin
|
begin
|
||||||
M.Destroying:=True;
|
M.Destroying:=True;
|
||||||
a:=fpc_wasm32_memory_atomic_notify(@M.Locked,MaxThreadSignal);
|
a:=fpc_wasm32_memory_atomic_notify(@M.Locked,MaxThreadSignal);
|
||||||
@ -190,6 +190,7 @@ begin
|
|||||||
InterLockedDecrement(M.Count);
|
InterLockedDecrement(M.Count);
|
||||||
if (M.Count=0) then
|
if (M.Count=0) then
|
||||||
begin
|
begin
|
||||||
|
M.Owner:=nil;
|
||||||
M.Locked:=0;
|
M.Locked:=0;
|
||||||
a:=fpc_wasm32_memory_atomic_notify(@M.Locked,1);
|
a:=fpc_wasm32_memory_atomic_notify(@M.Locked,1);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user