- Recompilación de RO para poner RemObjects_Core_D10 como paquete de runtime/designtime. git-svn-id: https://192.168.0.254/svn/Componentes.Terceros.RemObjects@3 b6239004-a887-0f4b-9937-50029ccdca16
220 lines
5.7 KiB
ObjectPascal
220 lines
5.7 KiB
ObjectPascal
unit uROThread;
|
|
|
|
{----------------------------------------------------------------------------}
|
|
{ RemObjects SDK Library - Core Library }
|
|
{ }
|
|
{ compiler: Delphi 5 and up, Kylix 2 and up }
|
|
{ platform: Win32, Linux }
|
|
{ }
|
|
{ (c)opyright RemObjects Software. all rights reserved. }
|
|
{ }
|
|
{ Using this code requires a valid license of the RemObjects SDK }
|
|
{ which can be obtained at http://www.remobjects.com. }
|
|
{----------------------------------------------------------------------------}
|
|
|
|
{$I RemObjects.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes {$IFDEF MSWINDOWS} , Windows {$ENDIF};
|
|
|
|
type
|
|
TROThread = class(TThread)
|
|
private
|
|
{$IFDEF MSWINDOWS}
|
|
fName:string;
|
|
fFreeWaiting: TObject; // TROEvent
|
|
fIsTerminated: Boolean;
|
|
{$ENDIF MSWINDOWS}
|
|
protected
|
|
{$IFDEF MSWINDOWS}
|
|
procedure SetName(const iName:string);
|
|
property Name:string read fName;
|
|
procedure DoTerminate; override;
|
|
{$ENDIF MSWINDOWS}
|
|
procedure Execute; override;
|
|
public
|
|
constructor Create(iCreateSuspended:Boolean; const iName:string='');
|
|
procedure TerminateWaitFor; virtual;
|
|
{$IFDEF MSWINDOWS}
|
|
function WaitFor: DWord; reintroduce;
|
|
{$IFNDEF FPC}
|
|
procedure Free; reintroduce; // Windows limitation workaround
|
|
{$ENDIF}
|
|
{$ENDIF MSWINDOWS}
|
|
end;
|
|
|
|
TROServerCheckMessageThread = class(TROThread)
|
|
private
|
|
fActive: boolean;
|
|
fInterval:integer;
|
|
fEvent:TObject;
|
|
procedure SetActive(const Value: boolean);
|
|
private
|
|
fOwner:TComponent;
|
|
protected
|
|
procedure Execute; override;
|
|
procedure CheckForMessages; virtual; abstract;
|
|
property Owner:TComponent read fOwner;
|
|
public
|
|
constructor Create(aName:string; aOwner:TComponent; iInterval:integer); reintroduce;
|
|
destructor Destroy; override;
|
|
procedure TerminateWaitFor; override;
|
|
property Active:boolean read fActive write SetActive;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
SysUtils, uROClasses;
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
type
|
|
TThreadNameInfo = record
|
|
FType: LongWord; // must be 0x1000
|
|
FName: PChar; // pointer to name (in user address space)
|
|
FThreadID: LongWord; // thread ID (-1 indicates caller thread)
|
|
FFlags: LongWord; // reserved for future use, must be zero
|
|
end;
|
|
{$ENDIF}
|
|
|
|
{ TROThread }
|
|
|
|
constructor TROThread.Create(iCreateSuspended:Boolean; const iName:string='');
|
|
begin
|
|
{$IFDEF MSWINDOWS}
|
|
fName := iName;
|
|
{$ENDIF MSWINDOWS}
|
|
inherited Create(iCreateSuspended)
|
|
end;
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
procedure TROThread.SetName(const iName:string);
|
|
var
|
|
ThreadNameInfo: TThreadNameInfo;
|
|
begin
|
|
if iName <> '' then begin
|
|
ThreadNameInfo.FType := $1000;
|
|
ThreadNameInfo.FName := PChar(iName);
|
|
ThreadNameInfo.FThreadID := $FFFFFFFF;
|
|
ThreadNameInfo.FFlags := 0;
|
|
try
|
|
//
|
|
// This exception is EXPECTED to be raised when creating a named thread in
|
|
// the debugger. You can safely ignore it and continue running the program.
|
|
//
|
|
RaiseException( $406D1388, 0, sizeof(ThreadNameInfo) div sizeof(LongWord), @ThreadNameInfo );
|
|
except
|
|
end;
|
|
end;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TROThread.Execute;
|
|
begin
|
|
{$IFDEF RemObjects_SetThreadName}
|
|
SetName(fName);
|
|
{$ENDIF RemObjects_SetThreadName}
|
|
end;
|
|
|
|
procedure TROThread.TerminateWaitFor;
|
|
begin
|
|
Terminate;
|
|
WaitFor();
|
|
end;
|
|
|
|
{$IFDEF MSWINDOWS}
|
|
|
|
function TROThread.WaitFor: DWord;
|
|
var
|
|
lEvent: TROEvent;
|
|
begin
|
|
result := 0;
|
|
if fIsTerminated then exit;
|
|
lEvent := TROEvent.Create(nil, false, false, '');
|
|
try
|
|
fFreeWaiting := lEvent;
|
|
Terminate;
|
|
while Suspended do Resume;
|
|
while not Terminated do lEvent.WaitFor(500); //lEvent.WaitFor(INFINITE);
|
|
sleep(10); // make sure it's actually terminated
|
|
fFreeWaiting := nil;
|
|
finally
|
|
lEvent.Free;
|
|
end;
|
|
end;
|
|
|
|
{$IFNDEF FPC}
|
|
procedure TROThread.Free;
|
|
begin
|
|
if self = nil then exit;
|
|
if ModuleIsLib then begin
|
|
// Windows doesn't return from EndThread until DllMain, so waitfor never returns either.
|
|
if fIsTerminated then
|
|
Destroy
|
|
else begin
|
|
FreeOnTerminate := true;
|
|
WaitFor;
|
|
end;
|
|
end else
|
|
Destroy;
|
|
end;
|
|
{$ENDIF}
|
|
|
|
procedure TROThread.DoTerminate;
|
|
begin
|
|
inherited;
|
|
fIsTerminated := true;
|
|
if fFreeWaiting <> nil then
|
|
TROEvent(fFreeWaiting).SetEvent;
|
|
end;
|
|
{$ENDIF MSWINDOWS}
|
|
|
|
|
|
{ TROServerCheckMessageThread }
|
|
|
|
constructor TROServerCheckMessageThread.Create(aName:string; aOwner:TComponent; iInterval:integer);
|
|
begin
|
|
inherited Create(true,aName);
|
|
fInterval := iInterval;
|
|
fOwner := aOwner;
|
|
fEvent := TROEvent.Create(nil,false,false,'');
|
|
Resume;
|
|
end;
|
|
|
|
destructor TROServerCheckMessageThread.Destroy;
|
|
begin
|
|
TerminateWaitFor();
|
|
FreeAndNil(fEvent);
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROServerCheckMessageThread.TerminateWaitFor;
|
|
begin
|
|
Resume();
|
|
TROEvent(fEvent).SetEvent();
|
|
inherited;
|
|
end;
|
|
|
|
procedure TROServerCheckMessageThread.Execute;
|
|
begin
|
|
inherited;
|
|
while not Terminated do begin
|
|
if not fActive then Suspend();
|
|
CheckForMessages();
|
|
if Terminated then break;
|
|
TROEvent(fEvent).WaitFor(fInterval*1000); { Interval is in seocnds, we need miliseconds. }
|
|
end;
|
|
end;
|
|
|
|
procedure TROServerCheckMessageThread.SetActive(const Value: boolean);
|
|
begin
|
|
if fActive <> Value then begin
|
|
fActive := Value;
|
|
if Active then Resume();
|
|
end;
|
|
end;
|
|
|
|
end.
|