TaskManager.RunTask() & TFuture.Chain(Proc)

This commit is contained in:
Michael Schimmel
2025-06-24 20:17:04 +02:00
parent a65a5f2b0a
commit 13c41d01b5
8 changed files with 120 additions and 165 deletions
+14 -28
View File
@@ -11,7 +11,7 @@ uses
Myc.Signals;
type
IMycTaskFactory = interface(IMycTaskManager)
IMycThreadPool = interface(TTaskManager.IMycTaskManager)
{$region 'property access'}
// Retrieves the number of worker threads.
function GetThreadCount: Integer;
@@ -49,7 +49,7 @@ type
property ThreadCount: Integer read GetThreadCount;
end;
TMycTaskFactory = class(TInterfacedObject, IMycTaskManager, IMycTaskFactory)
TMycTaskFactory = class(TInterfacedObject, TTaskManager.IMycTaskManager, IMycThreadPool)
type
ETaskException = class(Exception)
end;
@@ -65,9 +65,7 @@ type
FWorkStack: TMycAtomicStack<TProc>; // Stack of pending jobs
FWorkThreads: TArray<TThread>; // Array of worker threads
procedure WorkerThread;
class var
FTaskManagerLock: Integer;
class constructor CreateClass;
protected
procedure ExecuteJob;
function GetThreadCount: Integer;
@@ -81,16 +79,12 @@ type
procedure HandleException;
procedure EnqueueJob(const Job: TProc);
function Run(Job: TProc): TSignal.ISubscriber;
function CreateTask(const Gate: TState; const Proc: TProc): TSignal.TSubscription;
procedure WaitFor(const State: TState.IState);
procedure RunTask(const Gate: TState; const Proc: TProc);
procedure WaitFor(const State: TState);
procedure Teardown;
function InMainThread: Boolean;
function InWorkerThread: Boolean;
// Initialize global TaskManager
class procedure AquireTaskManager;
class procedure ReleaseTaskManager;
property ThreadsRunning: Integer read FThreadsRunning;
property WorkThreads: TArray<TThread> read FWorkThreads;
end;
@@ -147,6 +141,10 @@ begin
FWaitSemaphores.Push(TSemaphore.Create(nil, 0, 1, ''));
end;
class constructor TMycTaskFactory.CreateClass;
begin
end;
destructor TMycTaskFactory.Destroy;
begin
Teardown; // Perform cleanup and stop threads
@@ -188,7 +186,7 @@ begin
Result.NameThreadForDebugging(DbgName); // Set thread name for debugging
end;
function TMycTaskFactory.CreateTask(const Gate: TState; const Proc: TProc): TSignal.TSubscription;
procedure TMycTaskFactory.RunTask(const Gate: TState; const Proc: TProc);
begin
if Gate.IsSet then
begin
@@ -197,7 +195,7 @@ begin
else
begin
// The job will run when Gate notifies the subscriber returned by Run.
Result := Gate.Signal.Subscribe(Run(Proc));
Gate.Signal.Subscribe(Run(Proc));
end;
end;
@@ -289,20 +287,6 @@ begin
exit(false); // Not found in worker thread list
end;
class procedure TMycTaskFactory.AquireTaskManager;
begin
if not Assigned(TaskManager) then
TaskManager := TMycTaskFactory.Create;
inc(FTaskManagerLock);
end;
class procedure TMycTaskFactory.ReleaseTaskManager;
begin
dec(FTaskManagerLock);
if FTaskManagerLock = 0 then
TaskManager := nil;
end;
function TMycTaskFactory.Run(Job: TProc): TSignal.ISubscriber;
begin
if FTerminated <> 0 then
@@ -345,7 +329,7 @@ begin
end;
end;
procedure TMycTaskFactory.WaitFor(const State: TState.IState);
procedure TMycTaskFactory.WaitFor(const State: TState);
var
lock: TSemaphore; // This is System.SyncObjs.TSemaphore
begin
@@ -431,4 +415,6 @@ end;
initialization
IsMultiThread := true;
TaskManager := TMycTaskFactory.Create;
end.