Browse Source

* anonymous method overloads for synchronize/queue.

marcoonthegit 3 years ago
parent
commit
e5ac0b2689

+ 3 - 0
rtl/amicommon/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/atari/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/beos/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/embedded/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 3 - 0
rtl/freertos/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 3 - 0
rtl/gba/classes.pp

@@ -15,6 +15,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 4 - 0
rtl/go32v2/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/haiku/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 4 - 0
rtl/macos/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/msdos/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/nativent/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/nds/classes.pp

@@ -15,6 +15,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 3 - 0
rtl/netware/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/netwlibc/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 99 - 3
rtl/objpas/classes/classes.inc

@@ -305,9 +305,11 @@ procedure ExecuteThreadQueueEntry(aEntry: TThread.PThreadQueueEntry);
 begin
 begin
   if Assigned(aEntry^.Method) then
   if Assigned(aEntry^.Method) then
     aEntry^.Method()
     aEntry^.Method()
-  // enable once closures are supported
-  {else
-    aEntry^.ThreadProc();}
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+  else
+    if Assigned(aEntry^.ThreadProc) then
+      aEntry^.ThreadProc
+{$endif}
 end;
 end;
 
 
 
 
@@ -448,11 +450,74 @@ class procedure TThread.Synchronize(AThread: TThread; AMethod: TThreadMethod);
   end;
   end;
 
 
 
 
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+class procedure TThread.Synchronize(AThread: TThread; AProcedure: TThreadProcedure);
+  var
+    syncentry: PThreadQueueEntry;
+    thread: TThread;
+  begin
+{$ifdef FPC_HAS_FEATURE_THREADING}
+    if Assigned(AThread) and (AThread.ThreadID = GetCurrentThreadID) then
+{$else}
+    if Assigned(AThread) then
+{$endif}
+      thread := AThread
+    else if Assigned(CurrentThreadVar) then
+      thread := CurrentThreadVar
+    else begin
+      thread := Nil;
+      { use a local synchronize event }
+      New(syncentry);
+      FillChar(syncentry^, SizeOf(TThreadQueueEntry), 0);
+{$ifdef FPC_HAS_FEATURE_THREADING}
+      syncentry^.ThreadID := GetCurrentThreadID;
+      syncentry^.SyncEvent := RtlEventCreate;
+{$else}
+      syncentry^.ThreadID := 0{GetCurrentThreadID};
+      syncentry^.SyncEvent := nil{RtlEventCreate};
+{$endif}
+    end;
+
+    if Assigned(thread) then begin
+      { the Synchronize event is instantiated on demand }
+      thread.InitSynchronizeEvent;
+
+      syncentry := thread.FSynchronizeEntry;
+    end;
+
+    syncentry^.Exception := Nil;
+    syncentry^.ThreadProc := AProcedure;
+    try
+      ThreadQueueAppend(syncentry, False);
+    finally
+      syncentry^.ThreadProc := Nil;
+      syncentry^.Next := Nil;
+
+      if not Assigned(thread) then begin
+        { clean up again }
+{$ifdef FPC_HAS_FEATURE_THREADING}
+        RtlEventDestroy(syncentry^.SyncEvent);
+{$endif}
+        Dispose(syncentry);
+      end;
+    end;
+  end;
+{$endif}
+
+
 procedure TThread.Synchronize(AMethod: TThreadMethod);
 procedure TThread.Synchronize(AMethod: TThreadMethod);
   begin
   begin
     TThread.Synchronize(self,AMethod);
     TThread.Synchronize(self,AMethod);
   end;
   end;
 
 
+
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+procedure TThread.Synchronize(AProcedure: TThreadProcedure);
+  begin
+    TThread.Synchronize(self,AProcedure);
+  end;
+{$endif}
+
 Function PopThreadQueueHead : TThread.PThreadQueueEntry;
 Function PopThreadQueueHead : TThread.PThreadQueueEntry;
 
 
 begin
 begin
@@ -550,12 +615,24 @@ begin
   Queue(Self, aMethod);
   Queue(Self, aMethod);
 end;
 end;
 
 
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+procedure TThread.Queue(aProcedure: TThreadProcedure);
+begin
+  Queue(Self, aProcedure);
+end;
+{$endif}
 
 
 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);
 end;
 end;
 
 
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+class procedure TThread.Queue(aThread: TThread; aProcedure: TThreadProcedure); static;
+begin
+  InternalQueue(aThread, aProcedure, False);
+end;
+{$endif}
 
 
 class procedure TThread.InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean); static;
 class procedure TThread.InternalQueue(aThread: TThread; aMethod: TThreadMethod; aQueueIfMain: Boolean); static;
 var
 var
@@ -575,6 +652,25 @@ begin
   ThreadQueueAppend(queueentry, aQueueIfMain);
   ThreadQueueAppend(queueentry, aQueueIfMain);
 end;
 end;
 
 
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+class procedure TThread.InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean); static;
+var
+  queueentry: PThreadQueueEntry;
+begin
+  New(queueentry);
+  FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
+  queueentry^.Thread := aThread;
+{$ifdef FPC_HAS_FEATURE_THREADING}
+  queueentry^.ThreadID := GetCurrentThreadID;
+{$else}
+  queueentry^.ThreadID := 0{GetCurrentThreadID};
+{$endif}
+  queueentry^.ThreadProc := aProcedure;
+
+  { the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
+  ThreadQueueAppend(queueentry, aQueueIfMain);
+end;
+{$endif}
 
 
 procedure TThread.ForceQueue(aMethod: TThreadMethod);
 procedure TThread.ForceQueue(aMethod: TThreadMethod);
 begin
 begin

+ 21 - 2
rtl/objpas/classes/classesh.inc

@@ -1848,6 +1848,9 @@ type
   EThreadDestroyCalled = class(EThread);
   EThreadDestroyCalled = class(EThread);
   TSynchronizeProcVar = procedure;
   TSynchronizeProcVar = procedure;
   TThreadMethod = procedure of object;
   TThreadMethod = procedure of object;
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+  TThreadProcedure = reference to procedure;
+{$endif}
 
 
   TThreadReportStatus = Procedure(Const status : String) of Object;
   TThreadReportStatus = Procedure(Const status : String) of Object;
 
 
@@ -1870,8 +1873,9 @@ type
     PThreadQueueEntry = ^TThreadQueueEntry;
     PThreadQueueEntry = ^TThreadQueueEntry;
     TThreadQueueEntry = record
     TThreadQueueEntry = record
       Method: TThreadMethod;
       Method: TThreadMethod;
-      // uncomment once closures are supported
-      //ThreadProc: TThreadProcedure;
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+      ThreadProc: TThreadProcedure;
+{$endif}
       Thread: TThread;
       Thread: TThread;
       ThreadID: TThreadID;
       ThreadID: TThreadID;
       Exception: TObject;
       Exception: TObject;
@@ -1901,6 +1905,9 @@ type
     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); static;
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+    class procedure InternalQueue(aThread: TThread; aProcedure: TThreadProcedure; aQueueIfMain: Boolean); static;
+{$endif}
     procedure CallOnTerminate;
     procedure CallOnTerminate;
     function GetPriority: TThreadPriority;
     function GetPriority: TThreadPriority;
     procedure SetPriority(Value: TThreadPriority);
     procedure SetPriority(Value: TThreadPriority);
@@ -1918,7 +1925,13 @@ type
     procedure TerminatedSet; virtual;
     procedure TerminatedSet; virtual;
     procedure Execute; virtual; abstract;
     procedure Execute; virtual; abstract;
     procedure Synchronize(AMethod: TThreadMethod);
     procedure Synchronize(AMethod: TThreadMethod);
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+    procedure Synchronize(AProcedure : TThreadProcedure);
+{$endif}
     procedure Queue(aMethod: TThreadMethod);
     procedure Queue(aMethod: TThreadMethod);
+{$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+    procedure Queue(aProcedure: TThreadProcedure);
+{$endif}
     procedure ForceQueue(aMethod: TThreadMethod); inline;
     procedure ForceQueue(aMethod: TThreadMethod); inline;
     property ReturnValue: Integer read FReturnValue write FReturnValue;
     property ReturnValue: Integer read FReturnValue write FReturnValue;
     property Terminated: Boolean read FTerminated;
     property Terminated: Boolean read FTerminated;
@@ -1961,7 +1974,13 @@ type
     class procedure SetReturnValue(aValue: Integer); static;
     class procedure SetReturnValue(aValue: Integer); static;
     class function CheckTerminated: Boolean; static;
     class function CheckTerminated: Boolean; static;
     class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod);
     class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod);
+    {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+    class procedure Synchronize(AThread: TThread; AProcedure : TThreadProcedure);
+    {$endif}
     class procedure Queue(aThread: TThread; aMethod: TThreadMethod); static;
     class procedure Queue(aThread: TThread; aMethod: TThreadMethod); static;
+    {$ifdef FPC_HAS_REFERENCE_PROCEDURE}
+    class procedure Queue(aThread: TThread; AProcedure : TThreadProcedure); static;
+    {$endif}
     class procedure ForceQueue(aThread: TThread; aMethod: TThreadMethod); inline; static;
     class procedure ForceQueue(aThread: TThread; aMethod: TThreadMethod); inline; static;
     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;

+ 3 - 0
rtl/os2/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/sinclairql/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/symbian/classes.pp

@@ -14,6 +14,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 4 - 0
rtl/unix/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$IF FPC_FULLVERSION>=30301}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 4 - 0
rtl/wasi/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 3 - 0
rtl/wii/classes.pp

@@ -15,6 +15,9 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 unit Classes;
 unit Classes;
 
 

+ 4 - 0
rtl/win16/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}

+ 5 - 0
rtl/win32/classes.pp

@@ -15,6 +15,11 @@
 
 
 {$mode objfpc}
 {$mode objfpc}
 
 
+{$IF FPC_FULLVERSION>=30301}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}
 
 

+ 4 - 0
rtl/win64/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$IF FPC_FULLVERSION>=30301}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 { $define Win16Res}
 { $define Win16Res}

+ 4 - 0
rtl/wince/classes.pp

@@ -14,6 +14,10 @@
  **********************************************************************}
  **********************************************************************}
 
 
 {$mode objfpc}
 {$mode objfpc}
+{$modeswitch FUNCTIONREFERENCES}
+{$define FPC_HAS_REFERENCE_PROCEDURE}
+{$endif}
+
 
 
 { determine the type of the resource/form file }
 { determine the type of the resource/form file }
 {$define Win16Res}
 {$define Win16Res}