Browse Source

TMonitor.Wait temporarily unlocks through recursive calls.

Rika Ichinose 1 year ago
parent
commit
d1432b7302
1 changed files with 14 additions and 2 deletions
  1. 14 2
      packages/rtl-objpas/src/inc/fpmonitor.pp

+ 14 - 2
packages/rtl-objpas/src/inc/fpmonitor.pp

@@ -293,18 +293,30 @@ function TMonitorData.Wait(aLock : PMonitorData; aTimeout: Cardinal): Boolean;
 
 
 var
 var
   aPulse : TPulseData;
   aPulse : TPulseData;
+  PrevLockCount : Integer;
 
 
 begin
 begin
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' Begin Wait (aTimeout: ',aTimeOut,')');{$ENDIF}
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' Begin Wait (aTimeout: ',aTimeOut,')');{$ENDIF}
   aLock^.CheckLockOwner;
   aLock^.CheckLockOwner;
   aPulse:=TPulseData.Create;
   aPulse:=TPulseData.Create;
   AddToPulseData(@aPulse);
   AddToPulseData(@aPulse);
-  aLock^.Leave;
+
+  // Forcibly unlock through any amount of recursive acquisitions!
+  PrevLockCount:=aLock^.LockCount;
+  aLock^.LockCount:=0;
+  aLock^.LockOwnerThreadID:=0;
+  LeaveCriticalSection(aLock^.CriticalSection);
+
   Result:=aPulse.Wait(aTimeOut);
   Result:=aPulse.Wait(aTimeOut);
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' Wait Removing from Pulse data');{$ENDIF}
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' Wait Removing from Pulse data');{$ENDIF}
   RemoveFromPulseData(@aPulse);
   RemoveFromPulseData(@aPulse);
   aPulse.Done;
   aPulse.Done;
-  aLock^.Enter;
+
+  // Lock back as if nothing happened!
+  EnterCriticalSection(aLock^.CriticalSection);
+  aLock^.LockOwnerThreadID:=GetCurrentThreadId;
+  aLock^.LockCount:=PrevLockCount;
+
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' End Wait (aTimeout: ',aTimeOut,')');{$ENDIF}
   {$IFDEF DEBUG_MONITOR}Writeln(StdErr,GetTickCount64,': Thread ',GetCurrentThreadId,' End Wait (aTimeout: ',aTimeOut,')');{$ENDIF}
 end;
 end;