Changeset 246


Ignore:
Timestamp:
May 24, 2011, 12:34:59 PM (13 years ago)
Author:
george
Message:
  • Modified: Threading unit now use concept of virtual TThread classes derived from TVirtualThread abstract class. Currently it only implements enhanced base thread class. In additional other threading principles as cooperative threading can be implemented.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Common/UThreading.pas

    r245 r246  
    1212  TMethodCall = procedure of object;
    1313
     14
     15  { TVirtualThread }
     16
     17  TVirtualThread = class
     18  private
     19    function GetFreeOnTerminate: Boolean; virtual; abstract;
     20    function GetPriority: TThreadPriority; virtual; abstract;
     21    function GetSuspended: Boolean; virtual; abstract;
     22    function GetTerminated: Boolean; virtual; abstract;
     23    function GetThreadId: Integer; virtual; abstract;
     24    procedure SetFreeOnTerminate(const AValue: Boolean); virtual; abstract;
     25    procedure SetPriority(const AValue: TThreadPriority); virtual; abstract;
     26    procedure SetSuspended(const AValue: Boolean); virtual; abstract;
     27    procedure SetTerminated(const AValue: Boolean); virtual; abstract;
     28  public
     29    Name: string;
     30    procedure Execute; virtual; abstract;
     31    procedure Resume; virtual; abstract;
     32    procedure Suspend; virtual; abstract;
     33    procedure Start; virtual; abstract;
     34    procedure Terminate; virtual; abstract;
     35    procedure Synchronize(AMethod: TThreadMethod); virtual; abstract;
     36    procedure WaitFor; virtual; abstract;
     37    procedure Sleep(Delay: Integer); virtual; abstract;
     38    property FreeOnTerminate: Boolean read GetFreeOnTerminate
     39      write SetFreeOnTerminate;
     40    property Suspended: Boolean read GetSuspended
     41      write SetSuspended;
     42    property Priority: TThreadPriority read GetPriority write SetPriority;
     43    property Terminated: Boolean read GetTerminated write SetTerminated;
     44    property ThreadId: Integer read GetThreadId;
     45  end;
     46
     47  TListedThread = class;
     48
     49  { TListedThreadExecute }
     50
     51  TListedThreadExecute = class(TThread)
     52    Parent: TListedThread;
     53    procedure Execute; override;
     54  end;
     55
    1456  { TListedThread }
    1557
    16   TListedThread = class(TThread)
    17     Name: string;
     58  TListedThread = class(TVirtualThread)
     59  private
     60    FTerminated: Boolean;
     61    FThread: TListedThreadExecute;
     62    function GetFreeOnTerminate: Boolean; override;
     63    function GetPriority: TThreadPriority; override;
     64    function GetSuspended: Boolean; override;
     65    function GetTerminated: Boolean; override;
     66    function GetThreadId: Integer; override;
     67    procedure SetFreeOnTerminate(const AValue: Boolean); override;
     68    procedure SetPriority(const AValue: TThreadPriority); override;
     69    procedure SetSuspended(const AValue: Boolean); override;
     70    procedure SetTerminated(const AValue: Boolean); override;
     71  public
    1872    constructor Create(CreateSuspended: Boolean;
    1973                       const StackSize: SizeUInt = DefaultStackSize);
    2074    destructor Destroy; override;
    21     procedure Sleep(Delay: Integer);
    22     property Terminated;
     75    procedure Sleep(Delay: Integer); override;
     76    procedure Execute; override;
     77    procedure Resume; override;
     78    procedure Suspend; override;
     79    procedure Start; override;
     80    procedure Terminate; override;
     81    procedure Synchronize(AMethod: TThreadMethod); override;
     82    procedure WaitFor; override;
    2383  end;
    2484
     
    3393  end;
    3494
    35 var
    36   ThreadList: TObjectList; // TList<TListedThread>
     95  { TThreadList }
     96
     97  TThreadList = class(TObjectList)
     98    function FindById(Id: Integer): TVirtualThread;
     99    constructor Create;
     100  end;
     101
     102var
     103  ThreadList: TThreadList;
    37104  ThreadListLock: TCriticalSection;
    38105  OnException: TExceptionEvent;
     
    42109
    43110resourcestring
    44   SCurrentThreadNotFound = 'Current thread ID %d not found in list.';
     111  SCurrentThreadNotFound = 'Current thread ID %d not found in virtual thread list.';
    45112
    46113
     
    68135var
    69136  I: Integer;
    70   Thread: TListedThread;
     137  Thread: TVirtualThread;
    71138begin
    72139  if MainThreadID = ThreadID then Method
    73140  else begin
    74     I := 0;
    75     while (I < ThreadList.Count) and (TListedThread(ThreadList[I]).ThreadID <> ThreadID) do
    76       Inc(I);
    77     if I < ThreadList.Count then begin
    78       Thread := TListedThread(ThreadList[I]);
    79       TThread.Synchronize(Thread, Method);
     141    Thread := ThreadList.FindById(ThreadID);
     142    if Assigned(Thread) then begin
     143      Thread.Synchronize(Method);
    80144    end else raise Exception.Create(Format(SCurrentThreadNotFound, [ThreadID]));
    81145  end;
    82146end;
    83147
     148{ TVirtualThread }
     149
     150
     151{ TThreadList }
     152
     153function TThreadList.FindById(Id: Integer): TVirtualThread;
     154var
     155  I: Integer;
     156begin
     157  I := 0;
     158  while (I < ThreadList.Count) and (TVirtualThread(ThreadList[I]).ThreadID <> Id) do
     159    Inc(I);
     160  if I < ThreadList.Count then Result := TVirtualThread(ThreadList[I])
     161    else Result := nil;
     162end;
     163
     164constructor TThreadList.Create;
     165begin
     166  inherited Create;
     167  OwnsObjects := False;
     168end;
     169
     170{ TListedThreadExecute }
     171
     172procedure TListedThreadExecute.Execute;
     173begin
     174  try
     175    Parent.Execute;
     176  except
     177    on E: Exception do
     178      if Assigned(OnException) then
     179        OnException(Parent.FThread, E);
     180  end;
     181end;
     182
     183{ TVirtualThread }
     184
     185
    84186{ TListedThread }
     187
     188function TListedThread.GetFreeOnTerminate: Boolean;
     189begin
     190  Result := FThread.FreeOnTerminate;
     191end;
     192
     193function TListedThread.GetPriority: TThreadPriority;
     194begin
     195  Result := FThread.Priority;
     196end;
     197
     198function TListedThread.GetSuspended: Boolean;
     199begin
     200  Result := FThread.Suspended;
     201end;
     202
     203function TListedThread.GetTerminated: Boolean;
     204begin
     205  Result := FTerminated;
     206end;
     207
     208function TListedThread.GetThreadId: Integer;
     209begin
     210  Result := FThread.ThreadID;
     211end;
     212
     213procedure TListedThread.SetFreeOnTerminate(const AValue: Boolean);
     214begin
     215  FThread.FreeOnTerminate := AValue;
     216end;
     217
     218procedure TListedThread.SetPriority(const AValue: TThreadPriority);
     219begin
     220  FThread.Priority := AValue;
     221end;
     222
     223procedure TListedThread.SetSuspended(const AValue: Boolean);
     224begin
     225  FThread.Suspended := AValue;
     226end;
     227
     228procedure TListedThread.SetTerminated(const AValue: Boolean);
     229begin
     230  FTerminated := AValue;
     231  if AValue then FThread.Terminate;
     232end;
    85233
    86234constructor TListedThread.Create(CreateSuspended: Boolean;
    87235  const StackSize: SizeUInt);
    88236begin
    89   inherited;
     237  FThread := TListedThreadExecute.Create(True, StackSize);
     238  FThread.Parent := Self;
    90239  try
    91240    ThreadListLock.Acquire;
     
    94243    ThreadListLock.Release;
    95244  end;
     245  if CreateSuspended = False then FThread.Start;
    96246end;
    97247
     
    109259    ThreadListLock.Release;
    110260  end;
     261  FThread.Free;
    111262  inherited Destroy;
    112263end;
     
    123274    SysUtils.Sleep(Quantum);
    124275  end;
     276end;
     277
     278procedure TListedThread.Execute;
     279begin
     280end;
     281
     282procedure TListedThread.Resume;
     283begin
     284  FThread.Resume;
     285end;
     286
     287procedure TListedThread.Suspend;
     288begin
     289  FThread.Suspend;
     290end;
     291
     292procedure TListedThread.Start;
     293begin
     294  FThread.Start;
     295end;
     296
     297procedure TListedThread.Terminate;
     298begin
     299  FTerminated := True;
     300  FThread.Terminate;
     301end;
     302
     303procedure TListedThread.Synchronize(AMethod: TThreadMethod);
     304begin
     305  FThread.Synchronize(FThread, AMethod);
     306end;
     307
     308procedure TListedThread.WaitFor;
     309begin
     310  FThread.WaitFor;
    125311end;
    126312
     
    142328
    143329ThreadListLock := TCriticalSection.Create;
    144 ThreadList := TObjectList.Create;
    145 ThreadList.OwnsObjects := False;
     330ThreadList := TThreadList.Create;
    146331
    147332finalization
Note: See TracChangeset for help on using the changeset viewer.