Browse Source

* Add delay parameter to ForceQueue for Delphi compatibility

Michaël Van Canneyt 2 weeks ago
parent
commit
36dda17245
2 changed files with 48 additions and 15 deletions
  1. 43 11
      rtl/objpas/classes/classes.inc
  2. 5 4
      rtl/objpas/classes/classesh.inc

+ 43 - 11
rtl/objpas/classes/classes.inc

@@ -362,6 +362,7 @@ begin
 {$endif}
 {$endif}
   begin
   begin
     try
     try
+      Writeln('Immediate execute');
       ExecuteThreadQueueEntry(aEntry);
       ExecuteThreadQueueEntry(aEntry);
     finally
     finally
       if not Assigned(aEntry^.SyncEvent) then
       if not Assigned(aEntry^.SyncEvent) then
@@ -559,8 +560,12 @@ procedure TThread.Synchronize(AProcedure: TThreadProcedure);
 {$endif}
 {$endif}
 
 
 Function PopThreadQueueHead : TThread.PThreadQueueEntry;
 Function PopThreadQueueHead : TThread.PThreadQueueEntry;
+var
+  lPrev : TThread.PThreadQueueEntry;
+  lNow : TDateTime;
 
 
 begin
 begin
+  lPrev:=Nil;
   Result:=ThreadQueueHead;
   Result:=ThreadQueueHead;
   if (Result<>Nil) then
   if (Result<>Nil) then
     begin
     begin
@@ -569,10 +574,22 @@ begin
     try
     try
 {$endif}
 {$endif}
       Result:=ThreadQueueHead;
       Result:=ThreadQueueHead;
+      lNow:=Now;
+      While Assigned(Result) and (Result^.ExecuteAfter<>0) and (Result^.ExecuteAfter>lNow) do
+        begin
+        lPrev:=Result;
+        Result:=Result^.Next;
+        end;
       if Result<>Nil then
       if Result<>Nil then
-        ThreadQueueHead:=ThreadQueueHead^.Next;
-      if Not Assigned(ThreadQueueHead) then
-        ThreadQueueTail := Nil;
+        begin
+        if Assigned(lPrev) then
+          lPrev^.Next:=Result^.Next
+        else
+          ThreadQueueHead:=Result^.Next;
+        // if Result^.Next is Nil, it means we popped the last
+        if Not Assigned(Result^.Next) then
+           ThreadQueueTail := lPrev;
+        end;
 {$ifdef FPC_HAS_FEATURE_THREADING}
 {$ifdef FPC_HAS_FEATURE_THREADING}
     finally
     finally
       System.LeaveCriticalSection(ThreadQueueLock);
       System.LeaveCriticalSection(ThreadQueueLock);
@@ -666,17 +683,17 @@ end;
 
 
 class procedure TThread.Queue(aThread: TThread; aMethod: TThreadMethod); static;
 class procedure TThread.Queue(aThread: TThread; aMethod: TThreadMethod); static;
 begin
 begin
-  InternalQueue(aThread, aMethod, False);
+  InternalQueue(aThread, aMethod, False, 0);
 end;
 end;
 
 
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
 class procedure TThread.Queue(aThread: TThread; AProcedure: TThreadProcedure);
 class procedure TThread.Queue(aThread: TThread; AProcedure: TThreadProcedure);
 begin
 begin
-  InternalQueue(aThread, aProcedure, False);
+  InternalQueue(aThread, aProcedure, False, 0);
 end;
 end;
 {$endif}
 {$endif}
 
 
-class procedure TThread.InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean); static;
+class procedure TThread.InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean; aExecuteAfter: TDateTime); static;
 var
 var
   queueentry: PThreadQueueEntry;
   queueentry: PThreadQueueEntry;
 begin
 begin
@@ -684,13 +701,14 @@ begin
   FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
   FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
   queueentry^.Thread := aThread;
   queueentry^.Thread := aThread;
   queueentry^.Method := aMethod;
   queueentry^.Method := aMethod;
+  queueentry^.ExecuteAfter:=aExecuteAfter;
 
 
   { the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
   { the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
   ThreadQueueAppend(queueentry, aQueueIfMain);
   ThreadQueueAppend(queueentry, aQueueIfMain);
 end;
 end;
 
 
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
-class procedure TThread.InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean); static;
+class procedure TThread.InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean; aExecuteAfter: TDateTime); static;
 var
 var
   queueentry: PThreadQueueEntry;
   queueentry: PThreadQueueEntry;
 begin
 begin
@@ -698,6 +716,7 @@ begin
   FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
   FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
   queueentry^.Thread := aThread;
   queueentry^.Thread := aThread;
   queueentry^.ThreadProc := aProcedure;
   queueentry^.ThreadProc := aProcedure;
+  queueentry^.ExecuteAfter:=aExecuteAfter;
 
 
   { the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
   { the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
   ThreadQueueAppend(queueentry, aQueueIfMain);
   ThreadQueueAppend(queueentry, aQueueIfMain);
@@ -710,15 +729,28 @@ begin
 end;
 end;
 
 
 
 
-class procedure TThread.ForceQueue(aThread: TThread; aMethod: TThreadMethod); static;
+class procedure TThread.ForceQueue(aThread: TThread; aMethod: TThreadMethod; aDelay : Integer = 0); static;
+var
+  lEnd : TDateTime;
 begin
 begin
-  InternalQueue(aThread, aMethod, True);
+  if aDelay<>0 then
+    lEnd:=Now+aDelay*(1/MSecsPerDay)
+  else
+    lEnd:=0;
+  InternalQueue(aThread, aMethod, True, lEnd);
 end;
 end;
 
 
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
-class procedure TThread.ForceQueue(aThread: TThread; aMethod: TThreadProcedure); static;
+class procedure TThread.ForceQueue(aThread: TThread; aMethod: TThreadProcedure; aDelay : Integer = 0); static;
+
+var
+  lEnd : TDateTime;
 begin
 begin
-  InternalQueue(aThread, aMethod, True);
+  if aDelay<>0 then
+    lEnd:=Now+aDelay*(1/MSecsPerDay)
+  else
+    lEnd:=0;
+  InternalQueue(aThread, aMethod, True, lEnd);
 end;
 end;
 {$endif}
 {$endif}
 
 

+ 5 - 4
rtl/objpas/classes/classesh.inc

@@ -2263,6 +2263,7 @@ type
       Exception: TObject;
       Exception: TObject;
       SyncEvent: PRtlEvent;
       SyncEvent: PRtlEvent;
       Next: PThreadQueueEntry;
       Next: PThreadQueueEntry;
+      ExecuteAfter : TDateTime;
     end;
     end;
   public type
   public type
     TSystemTimes = record
     TSystemTimes = record
@@ -2286,9 +2287,9 @@ type
     FSynchronizeEntry: PThreadQueueEntry;
     FSynchronizeEntry: PThreadQueueEntry;
     class function GetCurrentThread: TThread; static;
     class function GetCurrentThread: TThread; static;
     class function GetIsSingleProcessor: Boolean; static; inline;
     class function GetIsSingleProcessor: Boolean; static; inline;
-    class procedure InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean); static;
+    class procedure InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean; aExecuteAfter: TDateTime); static;
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
 {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
-    class procedure InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean); static;
+    class procedure InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean; aExecuteAfter: TDateTime); static;
 {$endif}
 {$endif}
     procedure CallOnTerminate;
     procedure CallOnTerminate;
     function GetPriority: TThreadPriority;
     function GetPriority: TThreadPriority;
@@ -2366,9 +2367,9 @@ type
     {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
     {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
     class procedure Queue(aThread: TThread; AProcedure : TThreadProcedure); static;
     class procedure Queue(aThread: TThread; AProcedure : TThreadProcedure); static;
     {$endif}
     {$endif}
-    class procedure ForceQueue(aThread: TThread; aMethod: TThreadMethod); inline; static;
+    class procedure ForceQueue(aThread: TThread; aMethod: TThreadMethod; aDelay : Integer = 0); inline; static;
     {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
     {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
-    class procedure ForceQueue(aThread: TThread; aMethod: TThreadProcedure); inline; static;
+    class procedure ForceQueue(aThread: TThread; aMethod: TThreadProcedure; aDelay : Integer = 0); inline; static;
     {$endif}
     {$endif}
     class procedure RemoveQueuedEvents(aThread: TThread; aMethod: TThreadMethod); static;
     class procedure RemoveQueuedEvents(aThread: TThread; aMethod: TThreadMethod); static;
     class procedure RemoveQueuedEvents(aMethod: TThreadMethod); static;
     class procedure RemoveQueuedEvents(aMethod: TThreadMethod); static;