📄 idthreadmgrpool.pas
字号:
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 10383: IdThreadMgrPool.pas
{
{ Rev 1.0 2002.11.12 10:56:22 PM czhower
}
{
2002-06-23 -Andrew P.Rybin
-2 deadlock fix (and also in IdThread)
}
unit IdThreadMgrPool;
interface
uses
Classes,
IdThread, IdThreadMgr;
type
TIdThreadMgrPool = class(TIdThreadMgr)
protected
FPoolSize: Integer;
FThreadPool: TThreadList;
//
procedure ThreadStopped(AThread: TIdThread);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetThread: TIdThread; override;
procedure ReleaseThread(AThread: TIdThread); override;
procedure TerminateThreads; override;
published
property PoolSize: Integer read FPoolSize write FPoolSize default 0;
End;
implementation
uses
IdGlobal,
SysUtils;
{ TIdThreadMgrPool }
constructor TIdThreadMgrPool.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FThreadPool := TThreadList.Create;
end;
destructor TIdThreadMgrPool.Destroy;
var
i: integer;
LThreads: TList;
begin
FPoolSize := 0;
LThreads := FThreadPool.LockList;
try
for i:=0 to LThreads.Count-1 do begin
with TIdThread(LThreads[i]) do begin
//thread can use ComponentStreamSystem, we must prevent deadlock
//Best way for IdUser's: calling TcpServer.Active:=FALSE & TerminateThreads from OnDestroy
FreeOnTerminate := TRUE;
Terminate;
Start;
end;//with
end;
finally FThreadPool.UnlockList; end;
FreeAndNil(FThreadPool);
inherited Destroy;
end;
function TIdThreadMgrPool.GetThread: TIdThread;
var
LThreadPool: TList;
begin
LThreadPool := FThreadPool.LockList;
try
if LThreadPool.Count > 0 then begin
Result := TIdThread(LThreadPool[0]);
LThreadPool.Delete(0);
end else begin
Result := CreateNewThread;
Result.StopMode := smSuspend;
end;
finally FThreadPool.UnlockList; end;
ActiveThreads.Add(Result);
end;
procedure TIdThreadMgrPool.ReleaseThread(AThread: TIdThread);
var
LThreadPool: TList;
begin
with ActiveThreads.LockList do try // To avoid ReleaseThread-code is
if IndexOf(AThread)=-1 then exit; // executed multiple times, because
finally // AThread.Free call ReleaseThread
ActiveThreads.UnlockList; // again. Now we will detect the 2nd
end; // time, and jump out of the routine
ActiveThreads.Remove(AThread); // here.
LThreadPool := FThreadPool.LockList;
try
// PoolSize = 0 means that we will keep all active threads in the thread pool
if ((PoolSize > 0) and (LThreadPool.Count >= PoolSize))
or AThread.Terminated or AThread.Suspended then begin
AThread.OnStopped := NIL;
AThread.FreeOnTerminate := TRUE;
AThread.Terminate;
AThread.Start;//if suspended
end
else begin
AThread.OnStopped := ThreadStopped;
AThread.Stop;//go sleep
end;
finally FThreadPool.UnlockList; end;
End;//ReleaseThread
procedure TIdThreadMgrPool.TerminateThreads;
begin
inherited TerminateThreads;
with FThreadPool.LockList do
try
while Count > 0 do begin
with TIdThread(Items[0]) do begin
FreeOnTerminate := TRUE;
Terminate;
Start; //Stopped==TRUE because Terminated
end;//with
Delete(0);
end;
finally
FThreadPool.UnlockList;
end;
end;
procedure TIdThreadMgrPool.ThreadStopped(AThread: TIdThread);
begin
AThread.OnStopped := NIL; //work is done. prevent from unexpected usage
if Assigned(FThreadPool) and NOT AThread.Terminated then begin
FThreadPool.Add(AThread);
end
else begin
AThread.Terminate; //abnormal situation: application termination or what?
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -