Explorar o código

amicommon: add some naive RTLEventWaitFor implementation, add long standing tthread.inc patch by Sven. Synchronize/CheckSynchronize should now work on Amiga

git-svn-id: trunk@41584 -
Károly Balogh %!s(int64=6) %!d(string=hai) anos
pai
achega
bda626d450
Modificáronse 2 ficheiros con 35 adicións e 1 borrados
  1. 26 0
      rtl/amicommon/athreads.pp
  2. 9 1
      rtl/amicommon/tthread.inc

+ 26 - 0
rtl/amicommon/athreads.pp

@@ -741,6 +741,7 @@ end;
 Type  PINTRTLEvent = ^TINTRTLEvent;
       TINTRTLEvent = record
         isset: boolean;
+        Sem: TSignalSemaphore; // Semaphore to protect the whole stuff
       end;
 
 Function intRTLEventCreate: PRTLEvent;
@@ -749,6 +750,8 @@ var p:pintrtlevent;
 
 begin
   new(p);
+  p^.isset:=false;
+  InitSemaphore(@p^.Sem);
   result:=PRTLEVENT(p);
 end;
 
@@ -766,7 +769,9 @@ var p:pintrtlevent;
 
 begin
   p:=pintrtlevent(aevent);
+  ObtainSemaphore(@p^.Sem);
   p^.isset:=true;
+  ReleaseSemaphore(@p^.Sem);
 end;
 
 
@@ -775,7 +780,9 @@ var p:pintrtlevent;
 
 begin
   p:=pintrtlevent(aevent);
+  ObtainSemaphore(@p^.Sem);
   p^.isset:=false;
+  ReleaseSemaphore(@p^.Sem);
 end;
 
 
@@ -784,7 +791,15 @@ var p:pintrtlevent;
 
 begin
   p:=pintrtlevent(aevent);
+  ObtainSemaphore(@p^.Sem);
+  while not p^.isset do 
+    begin
+      ReleaseSemaphore(@p^.Sem);
+      DOSDelay(1);
+      ObtainSemaphore(@p^.Sem);
+    end;
   p^.isset:=false;
+  ReleaseSemaphore(@p^.Sem);
 end;
 
 procedure intRTLEventWaitForTimeout(AEvent: PRTLEvent;timeout : longint);
@@ -792,6 +807,17 @@ var
   p : pintrtlevent;
 begin
   p:=pintrtlevent(aevent);
+  timeout:=timeout div 20; // DOSDelay expects (1/50 seconds)
+  ObtainSemaphore(@p^.Sem);
+  while (not p^.isset) and (timeout > 0) do
+    begin
+      ReleaseSemaphore(@p^.Sem);
+      DOSDelay(1);
+      dec(timeout);
+      ObtainSemaphore(@p^.Sem);
+    end;
+  p^.isset:=false;
+  ReleaseSemaphore(@p^.Sem);
 end;
 
 

+ 9 - 1
rtl/amicommon/tthread.inc

@@ -120,6 +120,14 @@ end;
 
 function TThread.WaitFor: Integer;
 begin
+  if MainThreadID=GetCurrentThreadID then
+    {
+     FFinished is set after DoTerminate, which does a synchronize of OnTerminate,
+     so make sure synchronize works (or indeed any other synchronize that may be
+     in progress)
+    }
+    while not FFinished do
+      CheckSynchronize(100);
+
   result:=WaitForThreadTerminate(FThreadID,0);
-  FFinished:=(result = 0);
 end;