|
@@ -91,7 +91,12 @@ var
|
|
TThread.SpinWait() }
|
|
TThread.SpinWait() }
|
|
SpinWaitDummy: LongWord;
|
|
SpinWaitDummy: LongWord;
|
|
|
|
|
|
|
|
+
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
threadvar
|
|
threadvar
|
|
|
|
+{$else}
|
|
|
|
+var
|
|
|
|
+{$endif}
|
|
{ the instance of the current thread; in case of an external thread this is
|
|
{ the instance of the current thread; in case of an external thread this is
|
|
Nil until TThread.GetCurrentThread was called once (the RTLs need to ensure
|
|
Nil until TThread.GetCurrentThread was called once (the RTLs need to ensure
|
|
that threadvars are initialized with 0!) }
|
|
that threadvars are initialized with 0!) }
|
|
@@ -206,7 +211,9 @@ function ThreadProc(ThreadObjPtr: Pointer): PtrInt;
|
|
Thread.DoTerminate;
|
|
Thread.DoTerminate;
|
|
if FreeThread then
|
|
if FreeThread then
|
|
Thread.Free;
|
|
Thread.Free;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
EndThread(Result);
|
|
EndThread(Result);
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
{ system-dependent code }
|
|
{ system-dependent code }
|
|
@@ -218,7 +225,11 @@ constructor TThread.Create(CreateSuspended: Boolean;
|
|
begin
|
|
begin
|
|
inherited Create;
|
|
inherited Create;
|
|
if FExternalThread then
|
|
if FExternalThread then
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
FThreadID := GetCurrentThreadID
|
|
FThreadID := GetCurrentThreadID
|
|
|
|
+{$else}
|
|
|
|
+ FThreadID := 0{GetCurrentThreadID}
|
|
|
|
+{$endif}
|
|
else
|
|
else
|
|
SysCreate(CreateSuspended, StackSize);
|
|
SysCreate(CreateSuspended, StackSize);
|
|
end;
|
|
end;
|
|
@@ -228,8 +239,10 @@ destructor TThread.Destroy;
|
|
begin
|
|
begin
|
|
if not FExternalThread then begin
|
|
if not FExternalThread then begin
|
|
SysDestroy;
|
|
SysDestroy;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
if FHandle <> TThreadID(0) then
|
|
if FHandle <> TThreadID(0) then
|
|
CloseThread(FHandle);
|
|
CloseThread(FHandle);
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
RemoveQueuedEvents(Self);
|
|
RemoveQueuedEvents(Self);
|
|
DoneSynchronizeEvent;
|
|
DoneSynchronizeEvent;
|
|
@@ -279,10 +292,14 @@ end;
|
|
procedure ThreadQueueAppend(aEntry: TThread.PThreadQueueEntry);
|
|
procedure ThreadQueueAppend(aEntry: TThread.PThreadQueueEntry);
|
|
begin
|
|
begin
|
|
{ do we really need a synchronized call? }
|
|
{ do we really need a synchronized call? }
|
|
- if GetCurrentThreadID = MainThreadID then begin
|
|
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
|
|
+ if GetCurrentThreadID = MainThreadID then
|
|
|
|
+{$endif}
|
|
|
|
+ begin
|
|
ExecuteThreadQueueEntry(aEntry);
|
|
ExecuteThreadQueueEntry(aEntry);
|
|
if not Assigned(aEntry^.SyncEvent) then
|
|
if not Assigned(aEntry^.SyncEvent) then
|
|
Dispose(aEntry);
|
|
Dispose(aEntry);
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
end else begin
|
|
end else begin
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
try
|
|
try
|
|
@@ -307,6 +324,7 @@ begin
|
|
if Assigned(aEntry^.Exception) then
|
|
if Assigned(aEntry^.Exception) then
|
|
raise aEntry^.Exception;
|
|
raise aEntry^.Exception;
|
|
end;
|
|
end;
|
|
|
|
+{$endif def FPC_HAS_FEATURE_THREADING}
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -320,7 +338,11 @@ procedure TThread.InitSynchronizeEvent;
|
|
FillChar(FSynchronizeEntry^, SizeOf(TThreadQueueEntry), 0);
|
|
FillChar(FSynchronizeEntry^, SizeOf(TThreadQueueEntry), 0);
|
|
FSynchronizeEntry^.Thread := Self;
|
|
FSynchronizeEntry^.Thread := Self;
|
|
FSynchronizeEntry^.ThreadID := ThreadID;
|
|
FSynchronizeEntry^.ThreadID := ThreadID;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
FSynchronizeEntry^.SyncEvent := RtlEventCreate;
|
|
FSynchronizeEntry^.SyncEvent := RtlEventCreate;
|
|
|
|
+{$else}
|
|
|
|
+ FSynchronizeEntry^.SyncEvent := nil{RtlEventCreate};
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -329,7 +351,9 @@ procedure TThread.DoneSynchronizeEvent;
|
|
if not Assigned(FSynchronizeEntry) then
|
|
if not Assigned(FSynchronizeEntry) then
|
|
Exit;
|
|
Exit;
|
|
|
|
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
RtlEventDestroy(FSynchronizeEntry^.SyncEvent);
|
|
RtlEventDestroy(FSynchronizeEntry^.SyncEvent);
|
|
|
|
+{$endif}
|
|
Dispose(FSynchronizeEntry);
|
|
Dispose(FSynchronizeEntry);
|
|
FSynchronizeEntry := Nil;
|
|
FSynchronizeEntry := Nil;
|
|
end;
|
|
end;
|
|
@@ -343,8 +367,13 @@ class procedure TThread.Synchronize(AThread: TThread; AMethod: TThreadMethod);
|
|
{ use a local synchronize event }
|
|
{ use a local synchronize event }
|
|
New(syncentry);
|
|
New(syncentry);
|
|
FillChar(syncentry^, SizeOf(TThreadQueueEntry), 0);
|
|
FillChar(syncentry^, SizeOf(TThreadQueueEntry), 0);
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
syncentry^.ThreadID := GetCurrentThreadID;
|
|
syncentry^.ThreadID := GetCurrentThreadID;
|
|
syncentry^.SyncEvent := RtlEventCreate;
|
|
syncentry^.SyncEvent := RtlEventCreate;
|
|
|
|
+{$else}
|
|
|
|
+ syncentry^.ThreadID := 0{GetCurrentThreadID};
|
|
|
|
+ syncentry^.SyncEvent := nil{RtlEventCreate};
|
|
|
|
+{$endif}
|
|
end else begin
|
|
end else begin
|
|
{ the Synchronize event is instantiated on demand }
|
|
{ the Synchronize event is instantiated on demand }
|
|
AThread.InitSynchronizeEvent;
|
|
AThread.InitSynchronizeEvent;
|
|
@@ -361,7 +390,9 @@ class procedure TThread.Synchronize(AThread: TThread; AMethod: TThreadMethod);
|
|
|
|
|
|
if not Assigned(AThread) then begin
|
|
if not Assigned(AThread) then begin
|
|
{ clean up again }
|
|
{ clean up again }
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
RtlEventDestroy(syncentry^.SyncEvent);
|
|
RtlEventDestroy(syncentry^.SyncEvent);
|
|
|
|
+{$endif}
|
|
Dispose(syncentry);
|
|
Dispose(syncentry);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
@@ -378,16 +409,20 @@ begin
|
|
Result:=ThreadQueueHead;
|
|
Result:=ThreadQueueHead;
|
|
if (Result<>Nil) then
|
|
if (Result<>Nil) then
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
try
|
|
try
|
|
|
|
+{$endif}
|
|
Result:=ThreadQueueHead;
|
|
Result:=ThreadQueueHead;
|
|
if Result<>Nil then
|
|
if Result<>Nil then
|
|
ThreadQueueHead:=ThreadQueueHead^.Next;
|
|
ThreadQueueHead:=ThreadQueueHead^.Next;
|
|
if Not Assigned(ThreadQueueHead) then
|
|
if Not Assigned(ThreadQueueHead) then
|
|
ThreadQueueTail := Nil;
|
|
ThreadQueueTail := Nil;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
finally
|
|
finally
|
|
System.LeaveCriticalSection(ThreadQueueLock);
|
|
System.LeaveCriticalSection(ThreadQueueLock);
|
|
end;
|
|
end;
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
@@ -403,6 +438,7 @@ begin
|
|
{ first sanity check }
|
|
{ first sanity check }
|
|
if Not IsMultiThread then
|
|
if Not IsMultiThread then
|
|
Exit
|
|
Exit
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
{ second sanity check }
|
|
{ second sanity check }
|
|
else if GetCurrentThreadID<>MainThreadID then
|
|
else if GetCurrentThreadID<>MainThreadID then
|
|
raise EThread.CreateFmt(SCheckSynchronizeError,[GetCurrentThreadID]);
|
|
raise EThread.CreateFmt(SCheckSynchronizeError,[GetCurrentThreadID]);
|
|
@@ -436,7 +472,8 @@ begin
|
|
raise exceptobj;
|
|
raise exceptobj;
|
|
end;
|
|
end;
|
|
tmpentry := PopThreadQueueHead;
|
|
tmpentry := PopThreadQueueHead;
|
|
- end;
|
|
|
|
|
|
+ end
|
|
|
|
+{$endif};
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -471,7 +508,11 @@ begin
|
|
New(queueentry);
|
|
New(queueentry);
|
|
FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
|
|
FillChar(queueentry^, SizeOf(TThreadQueueEntry), 0);
|
|
queueentry^.Thread := aThread;
|
|
queueentry^.Thread := aThread;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
queueentry^.ThreadID := GetCurrentThreadID;
|
|
queueentry^.ThreadID := GetCurrentThreadID;
|
|
|
|
+{$else}
|
|
|
|
+ queueentry^.ThreadID := 0{GetCurrentThreadID};
|
|
|
|
+{$endif}
|
|
queueentry^.Method := aMethod;
|
|
queueentry^.Method := aMethod;
|
|
|
|
|
|
{ the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
|
|
{ the queueentry is freed by CheckSynchronize (or by RemoveQueuedEvents) }
|
|
@@ -487,8 +528,10 @@ begin
|
|
if not Assigned(aThread) and not Assigned(aMethod) then
|
|
if not Assigned(aThread) and not Assigned(aMethod) then
|
|
Exit;
|
|
Exit;
|
|
|
|
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
System.EnterCriticalSection(ThreadQueueLock);
|
|
try
|
|
try
|
|
|
|
+{$endif}
|
|
lastentry := Nil;
|
|
lastentry := Nil;
|
|
entry := ThreadQueueHead;
|
|
entry := ThreadQueueHead;
|
|
while Assigned(entry) do begin
|
|
while Assigned(entry) do begin
|
|
@@ -525,9 +568,11 @@ begin
|
|
if not Assigned(tmpentry^.SyncEvent) then
|
|
if not Assigned(tmpentry^.SyncEvent) then
|
|
Dispose(tmpentry);
|
|
Dispose(tmpentry);
|
|
end;
|
|
end;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
finally
|
|
finally
|
|
System.LeaveCriticalSection(ThreadQueueLock);
|
|
System.LeaveCriticalSection(ThreadQueueLock);
|
|
end;
|
|
end;
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -605,7 +650,9 @@ end;
|
|
|
|
|
|
class procedure TThread.Yield;
|
|
class procedure TThread.Yield;
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
ThreadSwitch;
|
|
ThreadSwitch;
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -656,7 +703,7 @@ begin
|
|
Result := SysUtils.GetTickCount64;
|
|
Result := SysUtils.GetTickCount64;
|
|
end;
|
|
end;
|
|
|
|
|
|
-{ TSimpleThread allows objects to create a threading method without defining
|
|
|
|
|
|
+{ TSimpleThread allows objects to create a threading method without defining
|
|
a new thread class }
|
|
a new thread class }
|
|
|
|
|
|
Type
|
|
Type
|
|
@@ -712,7 +759,7 @@ Type
|
|
|
|
|
|
|
|
|
|
{ TSimpleThread }
|
|
{ TSimpleThread }
|
|
-
|
|
|
|
|
|
+
|
|
constructor TSimpleThread.Create(ExecuteMethod: TThreadExecuteHandler; AOnTerminate: TNotifyEvent);
|
|
constructor TSimpleThread.Create(ExecuteMethod: TThreadExecuteHandler; AOnTerminate: TNotifyEvent);
|
|
begin
|
|
begin
|
|
FExecuteMethod := ExecuteMethod;
|
|
FExecuteMethod := ExecuteMethod;
|
|
@@ -727,7 +774,7 @@ begin
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TSimpleStatusThread }
|
|
{ TSimpleStatusThread }
|
|
-
|
|
|
|
|
|
+
|
|
constructor TSimpleStatusThread.Create(ExecuteMethod: TThreadExecuteStatusHandler;AOnStatus : TThreadStatusNotifyEvent; AOnTerminate: TNotifyEvent);
|
|
constructor TSimpleStatusThread.Create(ExecuteMethod: TThreadExecuteStatusHandler;AOnStatus : TThreadStatusNotifyEvent; AOnTerminate: TNotifyEvent);
|
|
begin
|
|
begin
|
|
FExecuteMethod := ExecuteMethod;
|
|
FExecuteMethod := ExecuteMethod;
|
|
@@ -745,11 +792,11 @@ end;
|
|
|
|
|
|
procedure TSimpleStatusThread.SetStatus(Const AStatus : String);
|
|
procedure TSimpleStatusThread.SetStatus(Const AStatus : String);
|
|
begin
|
|
begin
|
|
- If (AStatus=FStatus) then
|
|
|
|
|
|
+ If (AStatus=FStatus) then
|
|
exit;
|
|
exit;
|
|
FStatus:=AStatus;
|
|
FStatus:=AStatus;
|
|
- If Assigned(FOnStatus) then
|
|
|
|
- Synchronize(@DoStatus);
|
|
|
|
|
|
+ If Assigned(FOnStatus) then
|
|
|
|
+ Synchronize(@DoStatus);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TSimpleStatusThread.DoStatus;
|
|
procedure TSimpleStatusThread.DoStatus;
|
|
@@ -759,7 +806,7 @@ end;
|
|
|
|
|
|
|
|
|
|
{ TSimpleProcThread }
|
|
{ TSimpleProcThread }
|
|
-
|
|
|
|
|
|
+
|
|
constructor TSimpleProcThread.Create(ExecuteMethod: TThreadExecuteCallBack; AData : Pointer; AOnTerminate: TNotifyCallBack);
|
|
constructor TSimpleProcThread.Create(ExecuteMethod: TThreadExecuteCallBack; AData : Pointer; AOnTerminate: TNotifyCallBack);
|
|
begin
|
|
begin
|
|
FExecuteMethod := ExecuteMethod;
|
|
FExecuteMethod := ExecuteMethod;
|
|
@@ -780,11 +827,11 @@ procedure TSimpleProcThread.TerminateCallBack(Sender : TObject);
|
|
|
|
|
|
begin
|
|
begin
|
|
if Assigned(FCallOnTerminate) then
|
|
if Assigned(FCallOnTerminate) then
|
|
- FCallOnTerminate(Sender,FData);
|
|
|
|
|
|
+ FCallOnTerminate(Sender,FData);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TSimpleStatusProcThread }
|
|
{ TSimpleStatusProcThread }
|
|
-
|
|
|
|
|
|
+
|
|
constructor TSimpleStatusProcThread.Create(ExecuteMethod: TThreadExecuteStatusCallback; AData : Pointer; AOnStatus : TThreadStatusNotifyCallBack; AOnTerminate: TNotifyCallBack);
|
|
constructor TSimpleStatusProcThread.Create(ExecuteMethod: TThreadExecuteStatusCallback; AData : Pointer; AOnStatus : TThreadStatusNotifyCallBack; AOnTerminate: TNotifyCallBack);
|
|
begin
|
|
begin
|
|
FExecuteMethod := ExecuteMethod;
|
|
FExecuteMethod := ExecuteMethod;
|
|
@@ -805,11 +852,11 @@ end;
|
|
|
|
|
|
procedure TSimpleStatusProcThread.SetStatus(Const AStatus : String);
|
|
procedure TSimpleStatusProcThread.SetStatus(Const AStatus : String);
|
|
begin
|
|
begin
|
|
- If (AStatus=FStatus) then
|
|
|
|
|
|
+ If (AStatus=FStatus) then
|
|
exit;
|
|
exit;
|
|
FStatus:=AStatus;
|
|
FStatus:=AStatus;
|
|
- If Assigned(FOnStatus) then
|
|
|
|
- Synchronize(@DoStatus);
|
|
|
|
|
|
+ If Assigned(FOnStatus) then
|
|
|
|
+ Synchronize(@DoStatus);
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TSimpleStatusProcThread.DoStatus;
|
|
procedure TSimpleStatusProcThread.DoStatus;
|
|
@@ -821,7 +868,7 @@ procedure TSimpleStatusProcThread.TerminateCallBack(Sender : TObject);
|
|
|
|
|
|
begin
|
|
begin
|
|
if Assigned(FCallOnTerminate) then
|
|
if Assigned(FCallOnTerminate) then
|
|
- FCallOnTerminate(Sender,FData);
|
|
|
|
|
|
+ FCallOnTerminate(Sender,FData);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -840,7 +887,7 @@ end;
|
|
Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteStatusHandler; AOnStatus : TThreadStatusNotifyEvent; AOnTerminate : TNotifyEvent = Nil) : TThread;
|
|
Class Function TThread.ExecuteInThread(AMethod : TThreadExecuteStatusHandler; AOnStatus : TThreadStatusNotifyEvent; AOnTerminate : TNotifyEvent = Nil) : TThread;
|
|
|
|
|
|
begin
|
|
begin
|
|
- If Not Assigned(AOnStatus) then
|
|
|
|
|
|
+ If Not Assigned(AOnStatus) then
|
|
Raise EThread.Create(SErrStatusCallBackRequired);
|
|
Raise EThread.Create(SErrStatusCallBackRequired);
|
|
Result:=TSimpleStatusThread.Create(AMethod,AOnStatus,AOnTerminate);
|
|
Result:=TSimpleStatusThread.Create(AMethod,AOnStatus,AOnTerminate);
|
|
end;
|
|
end;
|
|
@@ -848,7 +895,7 @@ 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 = Nil; AOnTerminate : TNotifyCallBack = Nil) : TThread;
|
|
|
|
|
|
begin
|
|
begin
|
|
- If Not Assigned(AOnStatus) then
|
|
|
|
|
|
+ If Not Assigned(AOnStatus) then
|
|
Raise EThread.Create(SErrStatusCallBackRequired);
|
|
Raise EThread.Create(SErrStatusCallBackRequired);
|
|
Result:=TSimpleStatusProcThread.Create(AMethod,AData,AOnStatus,AOnTerminate);
|
|
Result:=TSimpleStatusProcThread.Create(AMethod,AData,AOnStatus,AOnTerminate);
|
|
end;
|
|
end;
|
|
@@ -1247,12 +1294,16 @@ function DefaultInitHandler(Instance: TComponent; RootAncestor: TClass): Boolean
|
|
end;
|
|
end;
|
|
|
|
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
GlobalNameSpace.BeginWrite;
|
|
GlobalNameSpace.BeginWrite;
|
|
try
|
|
try
|
|
|
|
+{$endif}
|
|
result:=doinit(Instance.ClassType);
|
|
result:=doinit(Instance.ClassType);
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
finally
|
|
finally
|
|
GlobalNameSpace.EndWrite;
|
|
GlobalNameSpace.EndWrite;
|
|
end;
|
|
end;
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
@@ -1390,7 +1441,11 @@ begin
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
threadvar
|
|
threadvar
|
|
|
|
+{$else}
|
|
|
|
+var
|
|
|
|
+{$endif}
|
|
GlobalLoaded, GlobalLists: TFpList;
|
|
GlobalLoaded, GlobalLists: TFpList;
|
|
|
|
|
|
procedure BeginGlobalLoading;
|
|
procedure BeginGlobalLoading;
|
|
@@ -2368,12 +2423,20 @@ end;
|
|
|
|
|
|
procedure CommonInit;
|
|
procedure CommonInit;
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
SynchronizeTimeoutEvent:=RtlEventCreate;
|
|
SynchronizeTimeoutEvent:=RtlEventCreate;
|
|
InitCriticalSection(ThreadQueueLock);
|
|
InitCriticalSection(ThreadQueueLock);
|
|
MainThreadID:=GetCurrentThreadID;
|
|
MainThreadID:=GetCurrentThreadID;
|
|
|
|
+{$else}
|
|
|
|
+ MainThreadID:=0{GetCurrentThreadID};
|
|
|
|
+{$endif}
|
|
ExternalThreads := TThreadList.Create;
|
|
ExternalThreads := TThreadList.Create;
|
|
- TThread.FProcessorCount := CPUCount;
|
|
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
InitCriticalsection(ResolveSection);
|
|
InitCriticalsection(ResolveSection);
|
|
|
|
+ TThread.FProcessorCount := CPUCount;
|
|
|
|
+{$else}
|
|
|
|
+ TThread.FProcessorCount := 1{CPUCount};
|
|
|
|
+{$endif}
|
|
InitHandlerList:=Nil;
|
|
InitHandlerList:=Nil;
|
|
FindGlobalComponentList:=nil;
|
|
FindGlobalComponentList:=nil;
|
|
IntConstList := TThreadList.Create;
|
|
IntConstList := TThreadList.Create;
|
|
@@ -2389,7 +2452,9 @@ var
|
|
i: Integer;
|
|
i: Integer;
|
|
tmpentry: TThread.PThreadQueueEntry;
|
|
tmpentry: TThread.PThreadQueueEntry;
|
|
begin
|
|
begin
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
GlobalNameSpace.BeginWrite;
|
|
GlobalNameSpace.BeginWrite;
|
|
|
|
+{$endif}
|
|
with IntConstList.LockList do
|
|
with IntConstList.LockList do
|
|
try
|
|
try
|
|
for i := 0 to Count - 1 do
|
|
for i := 0 to Count - 1 do
|
|
@@ -2401,7 +2466,9 @@ begin
|
|
ClassList.Free;
|
|
ClassList.Free;
|
|
ClassAliasList.Free;
|
|
ClassAliasList.Free;
|
|
RemoveFixupReferences(nil, '');
|
|
RemoveFixupReferences(nil, '');
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
DoneCriticalsection(ResolveSection);
|
|
DoneCriticalsection(ResolveSection);
|
|
|
|
+{$endif}
|
|
GlobalLists.Free;
|
|
GlobalLists.Free;
|
|
ComponentPages.Free;
|
|
ComponentPages.Free;
|
|
FreeAndNil(NeedResolving);
|
|
FreeAndNil(NeedResolving);
|
|
@@ -2424,7 +2491,9 @@ begin
|
|
ExternalThreads.UnlockList;
|
|
ExternalThreads.UnlockList;
|
|
end;
|
|
end;
|
|
FreeAndNil(ExternalThreads);
|
|
FreeAndNil(ExternalThreads);
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
RtlEventDestroy(SynchronizeTimeoutEvent);
|
|
RtlEventDestroy(SynchronizeTimeoutEvent);
|
|
|
|
+{$endif}
|
|
{ clean up the queue, but keep in mind that the entries used for Synchronize
|
|
{ clean up the queue, but keep in mind that the entries used for Synchronize
|
|
are owned by the corresponding TThread }
|
|
are owned by the corresponding TThread }
|
|
while Assigned(ThreadQueueHead) do begin
|
|
while Assigned(ThreadQueueHead) do begin
|
|
@@ -2433,7 +2502,9 @@ begin
|
|
if not Assigned(tmpentry^.SyncEvent) then
|
|
if not Assigned(tmpentry^.SyncEvent) then
|
|
Dispose(tmpentry);
|
|
Dispose(tmpentry);
|
|
end;
|
|
end;
|
|
|
|
+{$ifdef FPC_HAS_FEATURE_THREADING}
|
|
DoneCriticalSection(ThreadQueueLock);
|
|
DoneCriticalSection(ThreadQueueLock);
|
|
|
|
+{$endif}
|
|
end;
|
|
end;
|
|
|
|
|
|
{ TFiler implementation }
|
|
{ TFiler implementation }
|