196 lines
4.8 KiB
Plaintext
196 lines
4.8 KiB
Plaintext
|
{
|
||
|
$Project$
|
||
|
$Workfile$
|
||
|
$Revision$
|
||
|
$DateUTC$
|
||
|
$Id$
|
||
|
|
||
|
This file is part of the Indy (Internet Direct) project, and is offered
|
||
|
under the dual-licensing agreement described on the Indy website.
|
||
|
(http://www.indyproject.org/)
|
||
|
|
||
|
Copyright:
|
||
|
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||
|
}
|
||
|
{
|
||
|
$Log$
|
||
|
}
|
||
|
{
|
||
|
Rev 1.14 4/8/2004 11:55:30 AM BGooijen
|
||
|
Fix for D5
|
||
|
|
||
|
Rev 1.13 2004.03.01 5:12:38 PM czhower
|
||
|
-Bug fix for shutdown of servers when connections still existed (AV)
|
||
|
-Implicit HELP support in CMDserver
|
||
|
-Several command handler bugs
|
||
|
-Additional command handler functionality.
|
||
|
|
||
|
Rev 1.12 2004.01.20 10:03:30 PM czhower
|
||
|
InitComponent
|
||
|
|
||
|
Rev 1.11 2003.10.21 12:18:58 AM czhower
|
||
|
TIdTask support and fiber bug fixes.
|
||
|
|
||
|
Rev 1.10 2003.10.14 11:18:08 PM czhower
|
||
|
Fix for AV on shutdown and other bugs
|
||
|
|
||
|
Rev 1.9 2003.10.11 5:49:24 PM czhower
|
||
|
-VCL fixes for servers
|
||
|
-Chain suport for servers (Super core)
|
||
|
-Scheduler upgrades
|
||
|
-Full yarn support
|
||
|
|
||
|
Rev 1.8 2003.09.19 10:11:16 PM czhower
|
||
|
Next stage of fiber support in servers.
|
||
|
|
||
|
Rev 1.7 2003.09.19 11:54:30 AM czhower
|
||
|
-Completed more features necessary for servers
|
||
|
-Fixed some bugs
|
||
|
|
||
|
Rev 1.6 2003.09.18 4:10:24 PM czhower
|
||
|
Preliminary changes for Yarn support.
|
||
|
|
||
|
Rev 1.5 3/27/2003 5:15:36 PM BGooijen
|
||
|
Moved some code from subclasses here, made MaxThreads published
|
||
|
|
||
|
Rev 1.4 3/13/2003 10:18:36 AM BGooijen
|
||
|
Server side fibers, bug fixes
|
||
|
|
||
|
Rev 1.1 1/23/2003 11:06:04 AM BGooijen
|
||
|
|
||
|
Rev 1.0 1/17/2003 03:41:48 PM JPMugaas
|
||
|
Scheduler base class.
|
||
|
}
|
||
|
|
||
|
unit IdScheduler;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$i IdCompilerDefines.inc}
|
||
|
|
||
|
uses
|
||
|
{$IFDEF HAS_UNIT_Generics_Collections}
|
||
|
System.Generics.Collections,
|
||
|
{$ELSE}
|
||
|
{$IFDEF VCL_XE3_OR_ABOVE}
|
||
|
System.Classes,
|
||
|
{$ELSE}
|
||
|
Classes,
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
IdBaseComponent, IdThread, IdTask, IdYarn, IdThreadSafe;
|
||
|
|
||
|
type
|
||
|
{$IFDEF HAS_GENERICS_TThreadList}
|
||
|
TIdYarnThreadList = TIdThreadSafeObjectList<TIdYarn>;
|
||
|
TIdYarnList = TList<TIdYarn>;
|
||
|
{$ELSE}
|
||
|
// TODO: flesh out to match TIdThreadSafeObjectList<TIdYarn> and TList<TIdYarn> for non-Generics compilers
|
||
|
TIdYarnThreadList = TIdThreadSafeObjectList;
|
||
|
TIdYarnList = TList;
|
||
|
{$ENDIF}
|
||
|
|
||
|
TIdScheduler = class(TIdBaseComponent)
|
||
|
protected
|
||
|
FActiveYarns: TIdYarnThreadList;
|
||
|
//
|
||
|
procedure InitComponent; override;
|
||
|
public
|
||
|
destructor Destroy; override;
|
||
|
function AcquireYarn: TIdYarn; virtual; abstract;
|
||
|
procedure Init; virtual;
|
||
|
// ReleaseYarn is to remove a yarn from the list that has already been
|
||
|
// terminated (usually self termination);
|
||
|
procedure ReleaseYarn(AYarn: TIdYarn); virtual;
|
||
|
procedure StartYarn(AYarn: TIdYarn; ATask: TIdTask); virtual; abstract;
|
||
|
// TerminateYarn is to terminate a yarn explicitly and remove it also
|
||
|
procedure TerminateYarn(AYarn: TIdYarn); virtual; abstract;
|
||
|
procedure TerminateAllYarns; virtual;
|
||
|
//
|
||
|
property ActiveYarns: TIdYarnThreadList read FActiveYarns;
|
||
|
end;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses
|
||
|
//facilitate inlining only.
|
||
|
{$IFDEF DOTNET}
|
||
|
{$IFDEF USE_INLINE}
|
||
|
System.Threading,
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
{$IFDEF VCL_2010_OR_ABOVE}
|
||
|
{$IFDEF WINDOWS}
|
||
|
Windows,
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
{$IFDEF USE_VCL_POSIX}
|
||
|
Posix.SysSelect,
|
||
|
Posix.SysTime,
|
||
|
{$ENDIF}
|
||
|
{$IFDEF HAS_UNIT_Generics_Collections}
|
||
|
{$IFDEF VCL_XE3_OR_ABOVE}
|
||
|
System.Classes,
|
||
|
System.Types,
|
||
|
{$ELSE}
|
||
|
Classes,
|
||
|
{$ENDIF}
|
||
|
{$ELSE}
|
||
|
{$IFDEF VCL_XE3_OR_ABOVE}
|
||
|
System.Types, //here to facilitate inlining
|
||
|
{$ENDIF}
|
||
|
{$ENDIF}
|
||
|
IdGlobal, SysUtils;
|
||
|
|
||
|
{ TIdScheduler }
|
||
|
|
||
|
destructor TIdScheduler.Destroy;
|
||
|
begin
|
||
|
FreeAndNil(FActiveYarns);
|
||
|
inherited Destroy;
|
||
|
end;
|
||
|
|
||
|
procedure TIdScheduler.Init;
|
||
|
begin
|
||
|
end;
|
||
|
|
||
|
procedure TIdScheduler.InitComponent;
|
||
|
begin
|
||
|
inherited InitComponent;
|
||
|
FActiveYarns := TIdYarnThreadList.Create;
|
||
|
end;
|
||
|
|
||
|
procedure TIdScheduler.ReleaseYarn(AYarn: TIdYarn);
|
||
|
begin
|
||
|
ActiveYarns.Remove(AYarn);
|
||
|
end;
|
||
|
|
||
|
procedure TIdScheduler.TerminateAllYarns;
|
||
|
var
|
||
|
i: Integer;
|
||
|
LList: TIdYarnList;
|
||
|
begin
|
||
|
Assert(FActiveYarns<>nil);
|
||
|
|
||
|
while True do begin
|
||
|
// Must unlock each time to allow yarns that are terminating to remove themselves from the list
|
||
|
LList := FActiveYarns.LockList;
|
||
|
try
|
||
|
if LList.Count = 0 then begin
|
||
|
Break;
|
||
|
end;
|
||
|
for i := LList.Count - 1 downto 0 do begin
|
||
|
TerminateYarn(
|
||
|
{$IFDEF HAS_GENERICS_TList}LList.Items[i]{$ELSE}TIdYarn(LList.Items[i]){$ENDIF}
|
||
|
);
|
||
|
end;
|
||
|
finally
|
||
|
FActiveYarns.UnlockList;
|
||
|
end;
|
||
|
//TODO: Put terminate timeout check back
|
||
|
IndySleep(500); // Wait a bit before looping to prevent thrashing
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
end.
|