704 lines
19 KiB
Plaintext
704 lines
19 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.13 9/30/2004 2:26:04 PM BGooijen
|
|||
|
wrong property was referenced
|
|||
|
|
|||
|
Rev 1.12 2004.02.03 4:17:12 PM czhower
|
|||
|
For unit name changes.
|
|||
|
|
|||
|
Rev 1.11 2004.01.20 10:03:38 PM czhower
|
|||
|
InitComponent
|
|||
|
|
|||
|
Rev 1.10 09.11.2003 14:05:52 ARybin
|
|||
|
AV
|
|||
|
|
|||
|
Rev 1.9 08.11.2003 20:03:20 ARybin
|
|||
|
run-time active bug
|
|||
|
|
|||
|
Rev 1.8 10/15/2003 8:48:58 PM DSiders
|
|||
|
Added resource strings for exceptions raised when setting thread component
|
|||
|
properties.
|
|||
|
|
|||
|
Rev 1.7 2003.10.11 9:58:04 PM czhower
|
|||
|
Several bug fixes
|
|||
|
|
|||
|
Rev 1.6 2003.10.11 5:51:54 PM czhower
|
|||
|
-VCL fixes for servers
|
|||
|
-Chain suport for servers (Super core)
|
|||
|
-Scheduler upgrades
|
|||
|
-Full yarn support
|
|||
|
|
|||
|
Rev 1.5 2003.09.30 7:48:02 PM czhower
|
|||
|
Fixed Loop and ThreadName
|
|||
|
|
|||
|
Rev 1.4 9/18/2003 07:40:52 PM JPMugaas
|
|||
|
Removed IdGlobal.
|
|||
|
|
|||
|
Rev 1.3 9/16/2003 04:47:22 PM JPMugaas
|
|||
|
Made some code follow the Indy conventions so it's easier to debug.
|
|||
|
|
|||
|
Rev 1.2 2003.07.01 4:14:38 PM czhower
|
|||
|
ThreadName and Loop added. Other bugs fixed.
|
|||
|
|
|||
|
Rev 1.1 06.03.2003 12:16:52 ARybin
|
|||
|
adapted for new IdThread
|
|||
|
|
|||
|
Rev 1.0 11/13/2002 08:03:06 AM JPMugaas
|
|||
|
|
|||
|
2002-05-03 -Andrew P.Rybin
|
|||
|
-St<53>phane Grob<6F>ty (Fulgan) suggestion: component is Data owner, don't FreeAndNIL Data property
|
|||
|
-special TThread.OnTerminate support (it is sync-event)
|
|||
|
|
|||
|
2002-05-23 -APR
|
|||
|
-right support for Thread terminate
|
|||
|
}
|
|||
|
|
|||
|
unit IdThreadComponent;
|
|||
|
|
|||
|
{
|
|||
|
UnitName: IdThreadComponent
|
|||
|
Author: Andrew P.Rybin [magicode@mail.ru]
|
|||
|
Creation: 12.03.2002
|
|||
|
Version: 0.1.0
|
|||
|
Purpose:
|
|||
|
History: Based on my TmcThread
|
|||
|
}
|
|||
|
|
|||
|
interface
|
|||
|
{$I IdCompilerDefines.inc}
|
|||
|
//Put FPC into Delphi mode
|
|||
|
|
|||
|
uses
|
|||
|
Classes,
|
|||
|
IdBaseComponent, IdException, IdGlobal, IdThread, SysUtils;
|
|||
|
|
|||
|
const
|
|||
|
IdThreadComponentDefaultPriority = tpNormal;
|
|||
|
IdThreadComponentDefaultStopMode = smTerminate;
|
|||
|
|
|||
|
type
|
|||
|
TIdThreadComponent = class;
|
|||
|
|
|||
|
TIdExceptionThreadComponentEvent = procedure(Sender: TIdThreadComponent; AException: Exception) of object;
|
|||
|
TIdExceptionThreadComponentEventEx = procedure(Sender: TIdThreadComponent; AException: Exception; var VHandled: Boolean) of object;
|
|||
|
TIdNotifyThreadComponentEvent = procedure(Sender: TIdThreadComponent) of object;
|
|||
|
//TIdSynchronizeThreadComponentEvent = procedure(Sender: TIdThreadComponent; AData: Pointer) of object;
|
|||
|
|
|||
|
TIdThreadComponent = class(TIdBaseComponent)
|
|||
|
protected
|
|||
|
FActive: Boolean;
|
|||
|
FLoop: Boolean;
|
|||
|
FPriority : TIdThreadPriority;
|
|||
|
FStopMode : TIdThreadStopMode;
|
|||
|
FThread: TIdThread;
|
|||
|
FThreadName: string;
|
|||
|
//
|
|||
|
FOnAfterExecute: TIdNotifyThreadComponentEvent;
|
|||
|
FOnAfterRun: TIdNotifyThreadComponentEvent;
|
|||
|
FOnBeforeExecute: TIdNotifyThreadComponentEvent;
|
|||
|
FOnBeforeRun: TIdNotifyThreadComponentEvent;
|
|||
|
FOnCleanup: TIdNotifyThreadComponentEvent;
|
|||
|
FOnException: TIdExceptionThreadComponentEvent;
|
|||
|
FOnRun: TIdNotifyThreadComponentEvent;
|
|||
|
FOnStopped: TIdNotifyThreadComponentEvent;
|
|||
|
FOnTerminate: TIdNotifyThreadComponentEvent;
|
|||
|
FOnHandleRunException: TIdExceptionThreadComponentEventEx;
|
|||
|
//
|
|||
|
{$IFDEF INT_THREAD_PRIORITY}
|
|||
|
procedure DefineProperties(Filer: TFiler); override;
|
|||
|
procedure ReadPriority(Reader: TReader);
|
|||
|
procedure WritePriority(Writer: TWriter);
|
|||
|
{$ENDIF}
|
|||
|
procedure DoAfterExecute; virtual;
|
|||
|
procedure DoAfterRun; virtual;
|
|||
|
procedure DoBeforeExecute; virtual;
|
|||
|
procedure DoBeforeRun; virtual;
|
|||
|
procedure DoCleanup; virtual;
|
|||
|
procedure DoException(AThread: TIdThread; AException: Exception); virtual; //thev
|
|||
|
function DoHandleRunException(AException: Exception): Boolean; virtual;
|
|||
|
procedure DoRun; virtual;
|
|||
|
procedure DoStopped(AThread: TIdThread); virtual; //thev
|
|||
|
procedure DoTerminate(Sender: TObject); virtual; //thev
|
|||
|
function GetActive: Boolean;
|
|||
|
{$IFDEF USE_OBJECT_ARC}
|
|||
|
// When ARC is enabled, object references MUST be valid objects.
|
|||
|
// It is common for users to store non-object values, though, so
|
|||
|
// we will provide separate properties for those purposes
|
|||
|
//
|
|||
|
// TODO; use TValue instead of separating them
|
|||
|
//
|
|||
|
function GetDataObject: TObject;
|
|||
|
function GetDataValue: PtrInt;
|
|||
|
{$ELSE}
|
|||
|
function GetData: TObject;
|
|||
|
{$ENDIF}
|
|||
|
function GetHandle: TIdThreadHandle;
|
|||
|
function GetPriority: TIdThreadPriority;
|
|||
|
function GetReturnValue: Integer;
|
|||
|
function GetStopMode: TIdThreadStopMode;
|
|||
|
function GetStopped: Boolean;
|
|||
|
function GetSuspended: Boolean;
|
|||
|
function GetTerminatingException: string;
|
|||
|
function GetTerminatingExceptionClass: TClass;
|
|||
|
function GetTerminated: Boolean;
|
|||
|
procedure InitComponent; override;
|
|||
|
function IsRunning: Boolean;
|
|||
|
procedure Loaded; override;
|
|||
|
procedure SetActive(const AValue: Boolean); virtual;
|
|||
|
{$IFDEF USE_OBJECT_ARC}
|
|||
|
procedure SetDataObject(const AValue: TObject);
|
|||
|
procedure SetDataValue(const AValue: PtrInt);
|
|||
|
{$ELSE}
|
|||
|
procedure SetData(const AValue: TObject);
|
|||
|
{$ENDIF}
|
|||
|
procedure SetLoop(const AValue: Boolean);
|
|||
|
procedure SetThreadName(const AValue: string);
|
|||
|
procedure SetOnTerminate(const AValue: TIdNotifyThreadComponentEvent);
|
|||
|
procedure SetPriority(const AValue: TIdThreadPriority);
|
|||
|
procedure SetReturnValue(const AValue: Integer);
|
|||
|
procedure SetStopMode(const AValue: TIdThreadStopMode);
|
|||
|
public
|
|||
|
destructor Destroy; override;
|
|||
|
procedure Start; virtual;
|
|||
|
procedure Stop; virtual;
|
|||
|
procedure Synchronize(AMethod: TThreadMethod);
|
|||
|
procedure Terminate; virtual;
|
|||
|
procedure TerminateAndWaitFor; virtual;
|
|||
|
function WaitFor: UInt32;
|
|||
|
// Properties
|
|||
|
{$IFDEF USE_OBJECT_ARC}
|
|||
|
property DataObject: TObject read GetDataObject write SetDataObject;
|
|||
|
property DataValue: PtrInt read GetDataValue write SetDataValue;
|
|||
|
{$ELSE}
|
|||
|
property Data: TObject read GetData write SetData;
|
|||
|
{$ENDIF}
|
|||
|
property Handle: TIdThreadHandle read GetHandle;
|
|||
|
property ReturnValue: Integer read GetReturnValue write SetReturnValue;
|
|||
|
property Stopped: Boolean read GetStopped;
|
|||
|
property Suspended: Boolean read GetSuspended;
|
|||
|
property TerminatingException: string read GetTerminatingException;
|
|||
|
property TerminatingExceptionClass: TClass read GetTerminatingExceptionClass;
|
|||
|
property Terminated: Boolean read GetTerminated;
|
|||
|
{$IFDEF INT_THREAD_PRIORITY}
|
|||
|
property Priority: TIdThreadPriority read GetPriority write SetPriority;
|
|||
|
{$ENDIF}
|
|||
|
published
|
|||
|
property Active: Boolean read GetActive write SetActive;
|
|||
|
property Loop: Boolean read FLoop write SetLoop;
|
|||
|
{$IFNDEF INT_THREAD_PRIORITY}
|
|||
|
property Priority: TIdThreadPriority read GetPriority write SetPriority;
|
|||
|
{$ENDIF}
|
|||
|
property StopMode: TIdThreadStopMode read GetStopMode write SetStopMode;
|
|||
|
property ThreadName: string read FThreadName write SetThreadName;
|
|||
|
// Events
|
|||
|
property OnAfterExecute: TIdNotifyThreadComponentEvent read FOnAfterExecute write FOnAfterExecute;
|
|||
|
property OnAfterRun: TIdNotifyThreadComponentEvent read FOnAfterRun write FOnAfterRun;
|
|||
|
property OnBeforeExecute: TIdNotifyThreadComponentEvent read FOnBeforeExecute write FOnBeforeExecute;
|
|||
|
property OnBeforeRun: TIdNotifyThreadComponentEvent read FOnBeforeRun write FOnBeforeRun;
|
|||
|
property OnCleanup: TIdNotifyThreadComponentEvent read FOnCleanup write FOnCleanup;
|
|||
|
property OnException: TIdExceptionThreadComponentEvent read FOnException write FOnException;
|
|||
|
property OnHandleRunException: TIdExceptionThreadComponentEventEx
|
|||
|
read FOnHandleRunException write FOnHandleRunException;
|
|||
|
property OnRun: TIdNotifyThreadComponentEvent read FOnRun write FOnRun;
|
|||
|
property OnStopped: TIdNotifyThreadComponentEvent read FOnStopped
|
|||
|
write FOnStopped;
|
|||
|
property OnTerminate: TIdNotifyThreadComponentEvent read FOnTerminate
|
|||
|
write SetOnTerminate;
|
|||
|
end;
|
|||
|
|
|||
|
//For Component-writers ONLY!
|
|||
|
TIdThreadEx = class(TIdThread)
|
|||
|
protected
|
|||
|
FThreadComponent: TIdThreadComponent;
|
|||
|
//
|
|||
|
procedure AfterRun; override;
|
|||
|
procedure AfterExecute; override;
|
|||
|
procedure BeforeExecute; override;
|
|||
|
procedure BeforeRun; override;
|
|||
|
procedure Cleanup; override;
|
|||
|
function HandleRunException(AException: Exception): Boolean; override;
|
|||
|
procedure Run; override;
|
|||
|
public
|
|||
|
constructor Create(AThreadComponent: TIdThreadComponent); reintroduce;
|
|||
|
end;
|
|||
|
|
|||
|
implementation
|
|||
|
|
|||
|
uses
|
|||
|
IdResourceStringsCore;
|
|||
|
|
|||
|
{ TIdThreadEx }
|
|||
|
|
|||
|
procedure TIdThreadEx.AfterExecute;
|
|||
|
begin
|
|||
|
try
|
|||
|
FThreadComponent.DoAfterExecute;
|
|||
|
finally
|
|||
|
FThreadComponent.FActive := FALSE;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadEx.AfterRun;
|
|||
|
begin
|
|||
|
FThreadComponent.DoAfterRun;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadEx.BeforeExecute;
|
|||
|
begin
|
|||
|
FThreadComponent.DoBeforeExecute;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadEx.BeforeRun;
|
|||
|
begin
|
|||
|
FThreadComponent.DoBeforeRun;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadEx.Cleanup;
|
|||
|
begin
|
|||
|
inherited Cleanup;
|
|||
|
FThreadComponent.DoCleanup;
|
|||
|
end;
|
|||
|
|
|||
|
constructor TIdThreadEx.Create(AThreadComponent: TIdThreadComponent);
|
|||
|
begin
|
|||
|
inherited Create(True, AThreadComponent.Loop, iif(AThreadComponent.ThreadName = ''
|
|||
|
, AThreadComponent.Name, AThreadComponent.ThreadName));
|
|||
|
Exclude(FOptions, itoDataOwner); //TIdThreadComponent is data owner
|
|||
|
FThreadComponent := AThreadComponent;
|
|||
|
FOnException := FThreadComponent.DoException;
|
|||
|
FOnStopped := FThreadComponent.DoStopped;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadEx.HandleRunException(AException: Exception): Boolean;
|
|||
|
begin
|
|||
|
Result := FThreadComponent.DoHandleRunException(AException);
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadEx.Run;
|
|||
|
begin
|
|||
|
FThreadComponent.DoRun;
|
|||
|
end;
|
|||
|
|
|||
|
{ TIdThreadComponent }
|
|||
|
|
|||
|
{$IFDEF INT_THREAD_PRIORITY}
|
|||
|
procedure TIdThreadComponent.DefineProperties(Filer: TFiler);
|
|||
|
begin
|
|||
|
inherited;
|
|||
|
Filer.DefineProperty('Priority', ReadPriority, WritePriority, FPriority <> tpNormal);
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.ReadPriority(Reader: TReader);
|
|||
|
var
|
|||
|
Value: Integer;
|
|||
|
begin
|
|||
|
if Reader.NextValue = vaIdent then
|
|||
|
begin
|
|||
|
// an older DFM that stored TThreadPriority as enum value names is being read, so convert to integer ...
|
|||
|
case PosInStrArray(Reader.ReadIdent, ['tpIdle', 'tpLowest', 'tpLower', 'tpNormal', 'tpHigher', 'tpHighest', 'tpTimeCritical'], False) of {do not localize}
|
|||
|
0: Value := tpIdle;
|
|||
|
1: Value := tpLowest;
|
|||
|
2: Value := tpLower;
|
|||
|
3: Value := tpNormal;
|
|||
|
4: Value := tpHigher;
|
|||
|
5: Value := tpHighest;
|
|||
|
6: Value := tpTimeCritical;
|
|||
|
else
|
|||
|
Value := tpNormal;
|
|||
|
end;
|
|||
|
end else
|
|||
|
begin
|
|||
|
Value := Reader.ReadInteger;
|
|||
|
if Value < -20 then begin
|
|||
|
Value := -20;
|
|||
|
end
|
|||
|
else if Value > 19 then begin
|
|||
|
Value := 19;
|
|||
|
end;
|
|||
|
end;
|
|||
|
FPriority := Value;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.WritePriority(Writer: TWriter);
|
|||
|
begin
|
|||
|
Writer.WriteInteger(FPriority);
|
|||
|
end;
|
|||
|
{$ENDIF}
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoAfterExecute;
|
|||
|
begin
|
|||
|
if Assigned(FOnAfterExecute) then
|
|||
|
begin
|
|||
|
FOnAfterExecute(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoAfterRun;
|
|||
|
begin
|
|||
|
if Assigned(FOnAfterRun) then
|
|||
|
begin
|
|||
|
FOnAfterRun(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoBeforeExecute;
|
|||
|
begin
|
|||
|
if Assigned(FOnBeforeExecute) then
|
|||
|
begin
|
|||
|
FOnBeforeExecute(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoBeforeRun;
|
|||
|
begin
|
|||
|
if Assigned(FOnBeforeRun) then
|
|||
|
begin
|
|||
|
FOnBeforeRun(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoCleanup;
|
|||
|
begin
|
|||
|
if Assigned(FOnCleanup) then
|
|||
|
begin
|
|||
|
FOnCleanup(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
destructor TIdThreadComponent.Destroy;
|
|||
|
begin
|
|||
|
{FThread.TerminateAndWaitFor;}
|
|||
|
//make sure thread is not active before we attempt to destroy it
|
|||
|
if Assigned(FThread) then begin
|
|||
|
FThread.Terminate;
|
|||
|
FThread.Start;//resume for terminate
|
|||
|
end;
|
|||
|
IdDisposeAndNil(FThread);
|
|||
|
inherited Destroy;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoException(AThread: TIdThread; AException: Exception);
|
|||
|
begin
|
|||
|
if Assigned(FOnException) then begin
|
|||
|
FOnException(SELF,AException);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.DoHandleRunException(AException: Exception): Boolean;
|
|||
|
begin
|
|||
|
Result := FALSE;//not handled
|
|||
|
if Assigned(FOnHandleRunException) then begin
|
|||
|
FOnHandleRunException(SELF,AException,Result);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoStopped(AThread: TIdThread);
|
|||
|
begin
|
|||
|
if Assigned(FOnStopped) then begin
|
|||
|
FOnStopped(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoTerminate;
|
|||
|
begin
|
|||
|
if Assigned(FOnTerminate) then begin
|
|||
|
FOnTerminate(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
{$IFDEF USE_OBJECT_ARC}
|
|||
|
|
|||
|
function TIdThreadComponent.GetDataObject: TObject;
|
|||
|
begin
|
|||
|
Result := FThread.DataObject;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetDataValue: PtrInt;
|
|||
|
begin
|
|||
|
Result := FThread.DataValue;
|
|||
|
end;
|
|||
|
|
|||
|
{$ELSE}
|
|||
|
|
|||
|
function TIdThreadComponent.GetData: TObject;
|
|||
|
begin
|
|||
|
Result := FThread.Data;
|
|||
|
end;
|
|||
|
|
|||
|
{$ENDIF}
|
|||
|
|
|||
|
function TIdThreadComponent.GetHandle: TIdThreadHandle;
|
|||
|
begin
|
|||
|
Result := GetThreadHandle(FThread);
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetReturnValue: Integer;
|
|||
|
begin
|
|||
|
Result := FThread.ReturnValue;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetStopMode: TIdThreadStopMode;
|
|||
|
begin
|
|||
|
if FThread = NIL then begin
|
|||
|
Result := FStopMode;
|
|||
|
end else begin
|
|||
|
Result := FThread.StopMode;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetStopped: Boolean;
|
|||
|
begin
|
|||
|
if Assigned(FThread) then begin
|
|||
|
Result := FThread.Stopped;
|
|||
|
end else begin
|
|||
|
Result := TRUE;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetSuspended: Boolean;
|
|||
|
begin
|
|||
|
Result := FThread.Suspended;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetTerminated: Boolean;
|
|||
|
begin
|
|||
|
if Assigned(FThread) then begin
|
|||
|
Result := FThread.Terminated;
|
|||
|
end else begin
|
|||
|
Result := TRUE;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetTerminatingException: string;
|
|||
|
begin
|
|||
|
Result := FThread.TerminatingException;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetTerminatingExceptionClass: TClass;
|
|||
|
begin
|
|||
|
Result := FThread.TerminatingExceptionClass;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.Loaded;
|
|||
|
begin
|
|||
|
inherited Loaded;
|
|||
|
// Active = True must not be performed before all other props are loaded
|
|||
|
if Assigned(FThread) and Assigned(OnTerminate) then begin
|
|||
|
FThread.OnTerminate := DoTerminate;
|
|||
|
end;
|
|||
|
|
|||
|
if FActive then begin
|
|||
|
// Retoggle for load since we ignore during loading until all properties
|
|||
|
// are ready
|
|||
|
FActive := False;
|
|||
|
Active := True;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.DoRun;
|
|||
|
begin
|
|||
|
if Assigned(FOnRun) then begin
|
|||
|
FOnRun(SELF);
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetActive(const AValue: Boolean);
|
|||
|
begin
|
|||
|
if IsDesignTime or IsLoading then begin
|
|||
|
FActive := AValue;
|
|||
|
end
|
|||
|
else if Active <> AValue then begin
|
|||
|
if AValue then begin
|
|||
|
Start;
|
|||
|
end else begin
|
|||
|
Stop;
|
|||
|
end;
|
|||
|
FActive := AValue;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
{$IFDEF USE_OBJECT_ARC}
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetDataObject(const AValue: TObject);
|
|||
|
begin
|
|||
|
// this should not be accessed at design-time.
|
|||
|
FThread.DataObject := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetDataValue(const AValue: PtrInt);
|
|||
|
begin
|
|||
|
// this should not be accessed at design-time.
|
|||
|
FThread.DataValue := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
{$ELSE}
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetData(const AValue: TObject);
|
|||
|
begin
|
|||
|
// this should not be accessed at design-time.
|
|||
|
FThread.Data := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
{$ENDIF}
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetReturnValue(const AValue: Integer);
|
|||
|
begin
|
|||
|
// this should not be accessed at design-time.
|
|||
|
FThread.ReturnValue := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetStopMode(const AValue: TIdThreadStopMode);
|
|||
|
begin
|
|||
|
if Assigned(FThread) and NOT FThread.Terminated then begin
|
|||
|
FThread.StopMode := AValue;
|
|||
|
end;
|
|||
|
FStopMode := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.Start;
|
|||
|
begin
|
|||
|
if not IsDesignTime then begin
|
|||
|
if Assigned(FThread) and FThread.Terminated then begin
|
|||
|
IdDisposeAndNil(FThread);
|
|||
|
end;
|
|||
|
|
|||
|
if not Assigned(FThread) then begin
|
|||
|
FThread := TIdThreadEx.Create(Self);
|
|||
|
end;
|
|||
|
|
|||
|
// MUST read from F variants as thread is now created
|
|||
|
|
|||
|
if Assigned(FOnTerminate) then begin
|
|||
|
FThread.OnTerminate := DoTerminate;
|
|||
|
end else begin
|
|||
|
FThread.OnTerminate := nil;
|
|||
|
end;
|
|||
|
|
|||
|
FThread.Name := FThreadName;
|
|||
|
FThread.Loop := FLoop;
|
|||
|
FThread.Priority := FPriority;
|
|||
|
FThread.StopMode := FStopMode;
|
|||
|
|
|||
|
FThread.Start;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.Stop;
|
|||
|
begin
|
|||
|
if Assigned(FThread) then begin
|
|||
|
FThread.Stop;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.Synchronize(AMethod: TThreadMethod);
|
|||
|
begin
|
|||
|
FThread.Synchronize(AMethod);
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.Terminate;
|
|||
|
begin
|
|||
|
FThread.Terminate;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.TerminateAndWaitFor;
|
|||
|
begin
|
|||
|
FThread.TerminateAndWaitFor;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.WaitFor: UInt32;
|
|||
|
begin
|
|||
|
Result := FThread.WaitFor;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetPriority: TIdThreadPriority;
|
|||
|
begin
|
|||
|
if FThread <> nil then begin
|
|||
|
Result := FThread.Priority;
|
|||
|
end else begin
|
|||
|
Result := FPriority;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetPriority(const AValue: TIdThreadPriority);
|
|||
|
begin
|
|||
|
if Assigned(FThread) then begin
|
|||
|
if not FThread.Terminated then begin
|
|||
|
FThread.Priority := AValue;
|
|||
|
end;
|
|||
|
end;
|
|||
|
FPriority := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.GetActive: Boolean;
|
|||
|
begin
|
|||
|
Result := False;
|
|||
|
if IsDesignTime then begin
|
|||
|
Result := FActive;
|
|||
|
end else if FThread <> nil then begin
|
|||
|
Result := IsRunning;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetOnTerminate(const AValue: TIdNotifyThreadComponentEvent);
|
|||
|
begin
|
|||
|
FOnTerminate := AValue;
|
|||
|
if Assigned(FThread) then begin
|
|||
|
if Assigned(AValue) then begin
|
|||
|
FThread.OnTerminate := DoTerminate;
|
|||
|
end else begin
|
|||
|
FThread.OnTerminate := nil;
|
|||
|
end;
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetLoop(const AValue: Boolean);
|
|||
|
begin
|
|||
|
if IsRunning then begin
|
|||
|
raise EIdException.Create(RSThreadComponentLoopAlreadyRunning);
|
|||
|
end;
|
|||
|
FLoop := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.SetThreadName(const AValue: string);
|
|||
|
begin
|
|||
|
if IsRunning then begin
|
|||
|
raise EIdException.Create(RSThreadComponentThreadNameAlreadyRunning);
|
|||
|
end;
|
|||
|
FThreadName := AValue;
|
|||
|
end;
|
|||
|
|
|||
|
function TIdThreadComponent.IsRunning: Boolean;
|
|||
|
begin
|
|||
|
if FThread = nil then begin
|
|||
|
Result := False;
|
|||
|
end else begin
|
|||
|
Result := not FThread.Stopped
|
|||
|
end;
|
|||
|
end;
|
|||
|
|
|||
|
procedure TIdThreadComponent.InitComponent;
|
|||
|
begin
|
|||
|
inherited InitComponent;
|
|||
|
StopMode := IdThreadComponentDefaultStopMode;
|
|||
|
Priority := IdThreadComponentDefaultPriority;
|
|||
|
end;
|
|||
|
|
|||
|
end.
|
|||
|
|