From 29e2277d98fae1246789babafcd0585590d3f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Van=20Canneyt?= Date: Mon, 18 Dec 2023 16:51:39 +0100 Subject: [PATCH] * Add CreateAnonymousThread with anonymous procedure --- rtl/objpas/classes/classes.inc | 70 ++++++++++++++++++++++++++++----- rtl/objpas/classes/classesh.inc | 5 ++- 2 files changed, 65 insertions(+), 10 deletions(-) diff --git a/rtl/objpas/classes/classes.inc b/rtl/objpas/classes/classes.inc index 5cb5506c75..1b7324da2a 100644 --- a/rtl/objpas/classes/classes.inc +++ b/rtl/objpas/classes/classes.inc @@ -112,21 +112,38 @@ var type { this type is used if a thread is created using TThread.CreateAnonymousThread } + + { TAnonymousThread } + TAnonymousThread = class(TThread) private fProc: TProcedure; + {$ifdef FPC_HAS_REFERENCE_PROCEDURE} + fAnonProc : TThreadProcedure; + {$ENDIF} + FMethod : TThreadMethod; protected procedure Execute; override; public - { as in TThread aProc needs to be changed to TProc once closures are - supported } constructor Create(aProc: TProcedure); + {$ifdef FPC_HAS_REFERENCE_PROCEDURE} + constructor Create(aProc: TThreadProcedure); + {$ENDIF} + constructor Create(aProc: TThreadMethod); end; procedure TAnonymousThread.Execute; begin - fProc(); + {$ifdef FPC_HAS_REFERENCE_PROCEDURE} + if assigned(fAnonProc) then + fAnonProc() + else + {$ENDIF} + if assigned(FMethod) then + FMethod() + else + fProc(); end; @@ -138,6 +155,22 @@ begin fProc := aProc; end; +{$ifdef FPC_HAS_REFERENCE_PROCEDURE} +constructor TAnonymousThread.Create(aProc: TThreadProcedure); +begin + inherited Create(True); + FreeOnTerminate := True; + fAnonProc := aProc; +end; +{$ENDIF} + +constructor TAnonymousThread.Create(aProc: TThreadMethod); +begin + inherited Create(True); + FreeOnTerminate := True; + FMethod := aProc; +end; + type { this type is used by TThread.GetCurrentThread if the thread does not yet @@ -284,7 +317,7 @@ begin TerminatedSet; end; -Procedure TThread.TerminatedSet; +procedure TThread.TerminatedSet; begin // Empty, must be overridden. @@ -634,7 +667,7 @@ begin end; {$ifdef FPC_HAS_REFERENCE_PROCEDURE} -class procedure TThread.Queue(aThread: TThread; aProcedure: TThreadProcedure); static; +class procedure TThread.Queue(aThread: TThread; AProcedure: TThreadProcedure); begin InternalQueue(aThread, aProcedure, False); end; @@ -788,6 +821,23 @@ begin Result := TAnonymousThread.Create(aProc); end; +{$ifdef FPC_HAS_REFERENCE_PROCEDURE} +class function TThread.CreateAnonymousThread(aProc: TThreadProcedure): TThread; + +begin + if not Assigned(aProc) then + raise Exception.Create(SNoProcGiven); + Result := TAnonymousThread.Create(aProc); +end; +{$ENDIF} + +class function TThread.CreateAnonymousThread(aProc: TThreadMethod): TThread; +begin + if not Assigned(aProc) then + raise Exception.Create(SNoProcGiven); + Result := TAnonymousThread.Create(aProc); +end; + class procedure TThread.NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID); begin @@ -1029,19 +1079,20 @@ begin end; -Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteHandler; AOnTerminate : TNotifyEvent = Nil) : TThread; +class function TThread.ExecuteInThread(AMethod: TThreadExecuteHandler; AOnTerminate: TNotifyEvent): TThread; begin Result:=TSimpleThread.Create(AMethod,AOnTerminate); end; -Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteCallback; AData : Pointer; AOnTerminate : TNotifyCallback = Nil) : TThread; +class function TThread.ExecuteInThread(AMethod: TThreadExecuteCallback; AData: Pointer; AOnTerminate: TNotifyCallBack): TThread; begin Result:=TSimpleProcThread.Create(AMethod,AData,AOnTerminate); end; -Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteStatusHandler; AOnStatus : TThreadStatusNotifyEvent; AOnTerminate : TNotifyEvent = Nil) : TThread; +class function TThread.ExecuteInThread(AMethod: TThreadExecuteStatusHandler; AOnStatus: TThreadStatusNotifyEvent; + AOnTerminate: TNotifyEvent): TThread; begin If Not Assigned(AOnStatus) then @@ -1049,7 +1100,8 @@ begin Result:=TSimpleStatusThread.Create(AMethod,AOnStatus,AOnTerminate); end; -Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteStatusCallback; AOnStatus : TThreadStatusNotifyCallback;AData : Pointer = Nil; AOnTerminate : TNotifyCallBack = Nil) : TThread; +class function TThread.ExecuteInThread(AMethod: TThreadExecuteStatusCallback; AOnStatus: TThreadStatusNotifyCallback; + AData: Pointer; AOnTerminate: TNotifyCallBack): TThread; begin If Not Assigned(AOnStatus) then diff --git a/rtl/objpas/classes/classesh.inc b/rtl/objpas/classes/classesh.inc index 0de8344d80..ba916e5ac8 100644 --- a/rtl/objpas/classes/classesh.inc +++ b/rtl/objpas/classes/classesh.inc @@ -2284,8 +2284,11 @@ type constructor Create(CreateSuspended: Boolean; const StackSize: SizeUInt = DefaultStackSize); destructor Destroy; override; - { Note: Once closures are supported aProc will be changed to TProc } class function CreateAnonymousThread(aProc: TProcedure): TThread; static; + {$ifdef FPC_HAS_REFERENCE_PROCEDURE} + class function CreateAnonymousThread(aProc: TThreadProcedure): TThread; static; + {$ENDIF} + class function CreateAnonymousThread(aProc: TThreadMethod): TThread; static; class procedure NameThreadForDebugging(aThreadName: UnicodeString; aThreadID: TThreadID = TThreadID(-1)); static; inline; class procedure NameThreadForDebugging(aThreadName: AnsiString; aThreadID: TThreadID = TThreadID(-1)); static; inline; class procedure SetReturnValue(aValue: Integer); static;