Code formatting
This commit is contained in:
+38
-35
@@ -3,11 +3,15 @@ unit Myc.Core.Tasks;
|
||||
interface
|
||||
|
||||
uses
|
||||
System.SysUtils, System.Classes, System.SyncObjs,
|
||||
Myc.Core.Atomic, Myc.TaskManager, Myc.Signals;
|
||||
System.SysUtils,
|
||||
System.Classes,
|
||||
System.SyncObjs,
|
||||
Myc.Core.Atomic,
|
||||
Myc.TaskManager,
|
||||
Myc.Signals;
|
||||
|
||||
type
|
||||
IMycTaskFactory = interface( IMycTaskManager )
|
||||
IMycTaskFactory = interface(IMycTaskManager)
|
||||
{$region 'property access'}
|
||||
// Retrieves the number of worker threads.
|
||||
function GetThreadCount: Integer;
|
||||
@@ -46,8 +50,9 @@ type
|
||||
end;
|
||||
|
||||
TMycTaskFactory = class(TInterfacedObject, IMycTaskManager, IMycTaskFactory)
|
||||
type
|
||||
ETaskException = class(Exception) end;
|
||||
type
|
||||
ETaskException = class(Exception)
|
||||
end;
|
||||
private
|
||||
[volatile]
|
||||
FException: TObject; // Holds the first exception object from a worker thread
|
||||
@@ -60,8 +65,8 @@ type
|
||||
FWorkStack: TMycAtomicStack<TProc>; // Stack of pending jobs
|
||||
FWorkThreads: TArray<TThread>; // Array of worker threads
|
||||
procedure WorkerThread;
|
||||
class var
|
||||
FTaskManagerLock: Integer;
|
||||
class var
|
||||
FTaskManagerLock: Integer;
|
||||
|
||||
protected
|
||||
procedure ExecuteJob;
|
||||
@@ -139,7 +144,7 @@ begin
|
||||
for var i := 0 to High(FWorkThreads) do
|
||||
FWorkThreads[i].Start;
|
||||
|
||||
FWaitSemaphores.Push( TSemaphore.Create(nil, 0, 1, '') );
|
||||
FWaitSemaphores.Push(TSemaphore.Create(nil, 0, 1, ''));
|
||||
end;
|
||||
|
||||
destructor TMycTaskFactory.Destroy;
|
||||
@@ -159,14 +164,14 @@ end;
|
||||
|
||||
class function TMycTaskFactory.CreateAnonymousThread(const DbgName: String; const Proc: TProc): TThread;
|
||||
{$IFDEF MSWINDOWS}
|
||||
{$WARN SYMBOL_PLATFORM OFF}
|
||||
{$WARN SYMBOL_PLATFORM OFF}
|
||||
var
|
||||
prio: TThreadPriority;
|
||||
{$ENDIF MSWINDOWS}
|
||||
begin
|
||||
Result := TThread.CreateAnonymousThread(Proc);
|
||||
|
||||
{$IFDEF MSWINDOWS}
|
||||
{$IFDEF MSWINDOWS}
|
||||
// Set priority lower than MainThread priority if created from main thread
|
||||
if TThread.CurrentThread.ThreadID = MainThreadID then
|
||||
begin
|
||||
@@ -177,7 +182,7 @@ begin
|
||||
Result.Priority := prio;
|
||||
end;
|
||||
{$WARN SYMBOL_PLATFORM ON}
|
||||
{$ENDIF MSWINDOWS}
|
||||
{$ENDIF MSWINDOWS}
|
||||
|
||||
if DbgName <> '' then
|
||||
Result.NameThreadForDebugging(DbgName); // Set thread name for debugging
|
||||
@@ -187,12 +192,12 @@ function TMycTaskFactory.CreateTask(const Gate: TState; const Proc: TProc): TSta
|
||||
begin
|
||||
if Gate.IsSet then
|
||||
begin
|
||||
EnqueueJob( Proc );
|
||||
EnqueueJob(Proc);
|
||||
end
|
||||
else
|
||||
begin
|
||||
// The job will run when Gate notifies the subscriber returned by Run.
|
||||
Result := Gate.Subscribe( Run( Proc ) );
|
||||
Result := Gate.Subscribe(Run(Proc));
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -205,16 +210,18 @@ begin
|
||||
res := TLatch.Construct(1); // Changed to use direct static call on TMycLatch
|
||||
|
||||
capturedProc := Proc; // Capture Proc for the anonymous method
|
||||
CreateAnonymousThread('Thread',
|
||||
procedure
|
||||
begin
|
||||
try
|
||||
capturedProc(); // Execute the provided procedure
|
||||
finally
|
||||
capturedProc := nil; // Clear the captured proc
|
||||
res.Notify; // Signal completion via the latch's Notify method
|
||||
end;
|
||||
end).Start;
|
||||
CreateAnonymousThread(
|
||||
'Thread',
|
||||
procedure
|
||||
begin
|
||||
try
|
||||
capturedProc(); // Execute the provided procedure
|
||||
finally
|
||||
capturedProc := nil; // Clear the captured proc
|
||||
res.Notify; // Signal completion via the latch's Notify method
|
||||
end;
|
||||
end)
|
||||
.Start;
|
||||
|
||||
// Return the state interface of the latch
|
||||
exit(res.State);
|
||||
@@ -286,12 +293,12 @@ class procedure TMycTaskFactory.AquireTaskManager;
|
||||
begin
|
||||
if not Assigned(TaskManager) then
|
||||
TaskManager := TMycTaskFactory.Create;
|
||||
inc( FTaskManagerLock );
|
||||
inc(FTaskManagerLock);
|
||||
end;
|
||||
|
||||
class procedure TMycTaskFactory.ReleaseTaskManager;
|
||||
begin
|
||||
dec( FTaskManagerLock );
|
||||
dec(FTaskManagerLock);
|
||||
if FTaskManagerLock = 0 then
|
||||
TaskManager := nil;
|
||||
end;
|
||||
@@ -322,11 +329,7 @@ begin
|
||||
for i := 0 to High(FWorkThreads) do
|
||||
FWorkGate.Release;
|
||||
|
||||
TSpinWait.SpinUntil(
|
||||
function: Boolean
|
||||
begin
|
||||
Result := FThreadsRunning = 0;
|
||||
end);
|
||||
TSpinWait.SpinUntil(function: Boolean begin Result := FThreadsRunning = 0; end);
|
||||
|
||||
Assert(FThreadsRunning = 0);
|
||||
|
||||
@@ -357,7 +360,8 @@ begin
|
||||
if lock = nil then
|
||||
lock := TSemaphore.Create(nil, 0, 1, '');
|
||||
try
|
||||
{var subscription :=} State.Subscribe(TMycTaskWait.Create(lock));
|
||||
{var subscription :=}
|
||||
State.Subscribe(TMycTaskWait.Create(lock));
|
||||
lock.Acquire;
|
||||
finally
|
||||
FWaitSemaphores.Push(lock);
|
||||
@@ -386,8 +390,7 @@ end;
|
||||
|
||||
{ TMycPendingJob }
|
||||
|
||||
constructor TMycPendingJob.Create(OwnerTaskFactory: TMycTaskFactory; const
|
||||
JobProc: TProc);
|
||||
constructor TMycPendingJob.Create(OwnerTaskFactory: TMycTaskFactory; const JobProc: TProc);
|
||||
begin
|
||||
inherited Create;
|
||||
FOwner := OwnerTaskFactory;
|
||||
@@ -398,13 +401,13 @@ function TMycPendingJob.Notify: Boolean;
|
||||
var
|
||||
P: TProc;
|
||||
begin
|
||||
PPointer(@P)^ := TInterlocked.Exchange( PPointer(@FJob)^, nil );
|
||||
PPointer(@P)^ := TInterlocked.Exchange(PPointer(@FJob)^, nil);
|
||||
Result := Assigned(P);
|
||||
if Result then
|
||||
begin
|
||||
if Assigned(FOwner) then
|
||||
FOwner.EnqueueJob(P);
|
||||
P := nil;
|
||||
P := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user