mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 09:39:32 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			269 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
{
 | 
						|
    $Id$
 | 
						|
    This file is part of the Free Component Library (FCL)
 | 
						|
    Copyright (c) 1999-2002 by the Free Pascal development team
 | 
						|
 | 
						|
    See the file COPYING.FPC, included in this distribution,
 | 
						|
    for details about the copyright.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | 
						|
 | 
						|
 **********************************************************************}
 | 
						|
{****************************************************************************}
 | 
						|
{*                             TThread                                      *}
 | 
						|
{****************************************************************************}
 | 
						|
 | 
						|
(* OS/2 specific declarations - see unit DosCalls for descriptions *)
 | 
						|
 | 
						|
type
 | 
						|
 TByteArray = array [0..$fff0] of byte;
 | 
						|
 PByteArray = ^TByteArray;
 | 
						|
 | 
						|
 TThreadEntry = function (Param: pointer): longint; cdecl;
 | 
						|
 | 
						|
 TSysThreadIB = record
 | 
						|
                 TID, Priority, Version: longint;
 | 
						|
                 MCCount, MCForceFlag: word;
 | 
						|
                end;
 | 
						|
 PSysThreadIB = ^TSysThreadIB;
 | 
						|
 | 
						|
 TThreadInfoBlock = record
 | 
						|
                     Exh_Chain, Stack, StackLimit: pointer;
 | 
						|
                     TIB2: PSysThreadIB;
 | 
						|
                     Version, Ordinal: longint;
 | 
						|
                    end;
 | 
						|
 PThreadInfoBlock = ^TThreadInfoBlock;
 | 
						|
 PPThreadInfoBlock = ^PThreadInfoBlock;
 | 
						|
 | 
						|
 TProcessInfoBlock = record
 | 
						|
                      PID, ParentPID, HMTE: longint;
 | 
						|
                      Cmd, Env: PByteArray;
 | 
						|
                      flStatus, tType: longint;
 | 
						|
                     end;
 | 
						|
 PProcessInfoBlock = ^TProcessInfoBlock;
 | 
						|
 PPProcessInfoBlock = ^PProcessInfoBlock;
 | 
						|
 | 
						|
 | 
						|
const
 | 
						|
 deThread = 0;
 | 
						|
 deProcess = 1;
 | 
						|
 | 
						|
 dtSuspended = 1;
 | 
						|
 dtStack_Commited = 2;
 | 
						|
 | 
						|
 dtWait = 0;
 | 
						|
 dtNoWait = 1;
 | 
						|
 | 
						|
 | 
						|
procedure DosGetInfoBlocks (PATIB: PPThreadInfoBlock;
 | 
						|
              PAPIB: PPProcessInfoBlock); cdecl; external 'DOSCALLS' index 312;
 | 
						|
 | 
						|
function DosSetPriority (Scope, TrClass: cardinal; Delta: longint;
 | 
						|
             PortID: cardinal): cardinal; cdecl; external 'DOSCALLS' index 236;
 | 
						|
 | 
						|
procedure DosExit (Action, Result: cardinal); cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 233;
 | 
						|
 | 
						|
function DosCreateThread (var TID: cardinal; Address: TThreadEntry;
 | 
						|
      aParam: pointer; Flags: cardinal; StackSize: cardinal): cardinal; cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 311;
 | 
						|
 | 
						|
function DosKillThread (TID: cardinal): cardinal; cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 111;
 | 
						|
 | 
						|
function DosResumeThread (TID: cardinal): cardinal; cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 237;
 | 
						|
 | 
						|
function DosSuspendThread (TID: cardinal): cardinal; cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 238;
 | 
						|
 | 
						|
function DosWaitThread (var TID: cardinal; Option: cardinal): cardinal; cdecl;
 | 
						|
                                                 external 'DOSCALLS' index 349;
 | 
						|
 | 
						|
 | 
						|
const
 | 
						|
 Priorities: array [TThreadPriority] of word = ($100, $200, $207, $20F, $217,
 | 
						|
  $21F, $300);
 | 
						|
 ThreadCount: longint = 0;
 | 
						|
 | 
						|
(* Implementation of exported functions *)
 | 
						|
 | 
						|
procedure AddThread (T: TThread);
 | 
						|
begin
 | 
						|
 Inc (ThreadCount);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure RemoveThread (T: TThread);
 | 
						|
begin
 | 
						|
 Dec (ThreadCount);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.CallOnTerminate;
 | 
						|
begin
 | 
						|
 FOnTerminate (Self);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TThread.GetPriority: TThreadPriority;
 | 
						|
var
 | 
						|
 PTIB: PThreadInfoBlock;
 | 
						|
 PPIB: PProcessInfoBlock;
 | 
						|
 I: TThreadPriority;
 | 
						|
begin
 | 
						|
 DosGetInfoBlocks (@PTIB, @PPIB);
 | 
						|
 with PTIB^.TIB2^ do
 | 
						|
  if Priority >= $300 then GetPriority := tpTimeCritical else
 | 
						|
      if Priority < $200 then GetPriority := tpIdle else
 | 
						|
  begin
 | 
						|
   I := Succ (Low (TThreadPriority));
 | 
						|
   while (I < High (TThreadPriority)) and
 | 
						|
    (Priority - Priorities [I] <= Priorities [Succ (I)] - Priority) do Inc (I);
 | 
						|
   GetPriority := I;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.SetPriority(Value: TThreadPriority);
 | 
						|
var
 | 
						|
 PTIB: PThreadInfoBlock;
 | 
						|
 PPIB: PProcessInfoBlock;
 | 
						|
begin
 | 
						|
 DosGetInfoBlocks (@PTIB, @PPIB);
 | 
						|
(*
 | 
						|
 PTIB^.TIB2^.Priority := Priorities [Value];
 | 
						|
*)
 | 
						|
 DosSetPriority (2, High (Priorities [Value]),
 | 
						|
                     Low (Priorities [Value]) - PTIB^.TIB2^.Priority, FHandle);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.SetSuspended(Value: Boolean);
 | 
						|
begin
 | 
						|
 if Value <> FSuspended then
 | 
						|
 begin
 | 
						|
  if Value then Suspend else Resume;
 | 
						|
 end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.DoTerminate;
 | 
						|
begin
 | 
						|
 if Assigned (FOnTerminate) then Synchronize (@CallOnTerminate);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.Synchronize(Method: TThreadMethod);
 | 
						|
begin
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function ThreadProc(Args: pointer): Integer; cdecl;
 | 
						|
var
 | 
						|
  FreeThread: Boolean;
 | 
						|
  Thread: TThread absolute Args;
 | 
						|
begin
 | 
						|
  try
 | 
						|
    Thread.Execute;
 | 
						|
  except
 | 
						|
    Thread.FFatalException := TObject(AcquireExceptionObject);
 | 
						|
  end;
 | 
						|
  FreeThread := Thread.FFreeOnTerminate;
 | 
						|
  Result := Thread.FReturnValue;
 | 
						|
  Thread.FFinished := True;
 | 
						|
  Thread.DoTerminate;
 | 
						|
  if FreeThread then Thread.Free;
 | 
						|
  DosExit (deThread, Result);
 | 
						|
end;
 | 
						|
 | 
						|
constructor TThread.Create(CreateSuspended: Boolean);
 | 
						|
var
 | 
						|
  Flags: cardinal;
 | 
						|
begin
 | 
						|
  inherited Create;
 | 
						|
  AddThread (Self);
 | 
						|
  FSuspended := CreateSuspended;
 | 
						|
  Flags := dtStack_Commited;
 | 
						|
  if FSuspended then Flags := Flags or dtSuspended;
 | 
						|
  if DosCreateThread (cardinal (FThreadID), @ThreadProc, pointer (Self),
 | 
						|
                                                        Flags, 16384) <> 0 then
 | 
						|
  begin
 | 
						|
   FFinished := true;
 | 
						|
   Destroy;
 | 
						|
  end else FHandle := FThreadID;
 | 
						|
  IsMultiThread := true;
 | 
						|
  FFatalException := nil;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
destructor TThread.Destroy;
 | 
						|
begin
 | 
						|
 if not FFinished and not Suspended then
 | 
						|
 begin
 | 
						|
  Terminate;
 | 
						|
  WaitFor;
 | 
						|
 end;
 | 
						|
 if FHandle <> -1 then DosKillThread (cardinal (FHandle));
 | 
						|
 FFatalException.Free;
 | 
						|
 FFatalException := nil;
 | 
						|
 inherited Destroy;
 | 
						|
 RemoveThread (Self);
 | 
						|
end;
 | 
						|
 | 
						|
procedure TThread.Resume;
 | 
						|
begin
 | 
						|
 FSuspended := not (DosResumeThread (cardinal (FHandle)) = 0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.Suspend;
 | 
						|
begin
 | 
						|
 FSuspended := DosSuspendThread (cardinal (FHandle)) = 0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TThread.Terminate;
 | 
						|
begin
 | 
						|
 FTerminated := true;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TThread.WaitFor: Integer;
 | 
						|
var
 | 
						|
 FH: cardinal;
 | 
						|
begin
 | 
						|
 WaitFor := DosWaitThread (FH, dtWait);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{
 | 
						|
  $Log$
 | 
						|
  Revision 1.4  2003-10-16 19:24:24  hajny
 | 
						|
    * another longint2cardinal fix
 | 
						|
 | 
						|
  Revision 1.3  2003/10/14 21:19:12  hajny
 | 
						|
    * another longint2cardinal fix
 | 
						|
 | 
						|
  Revision 1.2  2003/10/13 21:17:31  hajny
 | 
						|
    * longint to cardinal corrections
 | 
						|
 | 
						|
  Revision 1.1  2003/10/06 21:01:07  peter
 | 
						|
    * moved classes unit to rtl
 | 
						|
 | 
						|
  Revision 1.8  2003/10/06 17:06:55  florian
 | 
						|
    * applied Johannes Berg's patch for exception handling in threads
 | 
						|
 | 
						|
  Revision 1.7  2003/02/20 17:12:39  hajny
 | 
						|
    * fixes for OS/2 v2.1 incompatibility
 | 
						|
 | 
						|
  Revision 1.6  2002/09/07 15:15:27  peter
 | 
						|
    * old logs removed and tabs fixed
 | 
						|
 | 
						|
  Revision 1.5  2002/02/10 13:38:14  hajny
 | 
						|
    * DosCalls dependency removed to avoid type redefinitions
 | 
						|
 | 
						|
}
 |