123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- { Thread management routines }
- type
- PRaiseFrame = ^TRaiseFrame;
- TRaiseFrame = record
- NextRaise: PRaiseFrame;
- ExceptAddr: Pointer;
- ExceptObject: TObject;
- ExceptionRecord: pointer; {PExceptionRecord}
- end;
- constructor TThread.Create(CreateSuspended: Boolean;
- const StackSize: SizeUInt = DefaultStackSize);
- var
- Flags: Integer;
- begin
- inherited Create;
- FSuspended := CreateSuspended;
- Flags := 0;
- if CreateSuspended then Flags := CREATE_SUSPENDED;
- FHandle := BeginThread(nil, StackSize, @ThreadProc, pointer(self), Flags,
- FThreadID);
- if FHandle = TThreadID(0) then
- raise EThread.create('Failed to create new thread, code:'+inttostr(getlasterror));
- FFatalException := nil;
- end;
- destructor TThread.Destroy;
- begin
- if FHandle<>0 then
- begin
- if not FFinished and not Suspended then
- begin
- Terminate;
- WaitFor;
- end;
- CloseHandle(FHandle);
- end;
- FFatalException.Free;
- FFatalException := nil;
- inherited Destroy;
- end;
- procedure TThread.CallOnTerminate;
- begin
- FOnTerminate(Self);
- end;
- procedure TThread.DoTerminate;
- begin
- if Assigned(FOnTerminate) then
- Synchronize(@CallOnTerminate);
- end;
- const
- Priorities: array [TThreadPriority] of Integer =
- (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,
- THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,
- THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);
- function TThread.GetPriority: TThreadPriority;
- var
- P: Integer;
- I: TThreadPriority;
- begin
- P := GetThreadPriority(FHandle);
- Result := tpNormal;
- for I := Low(TThreadPriority) to High(TThreadPriority) do
- if Priorities[I] = P then Result := I;
- end;
- procedure TThread.SetPriority(Value: TThreadPriority);
- begin
- SetThreadPriority(FHandle, Priorities[Value]);
- end;
- procedure TThread.SetSuspended(Value: Boolean);
- begin
- if Value <> FSuspended then
- if Value then
- Suspend
- else
- Resume;
- end;
- procedure TThread.Suspend;
- begin
- FSuspended := True;
- SuspendThread(FHandle);
- end;
- procedure TThread.Resume;
- begin
- if ResumeThread(FHandle) = 1 then FSuspended := False;
- end;
- procedure TThread.Terminate;
- begin
- FTerminated := True;
- end;
- function TThread.WaitFor: Integer;
- var
- Msg: TMsg;
- WaitHandles : array[0..1] of THandle;
- begin
- if GetCurrentThreadID = MainThreadID then
- begin
- WaitHandles[0]:=FHandle;
- WaitHandles[1]:=THandle(SynchronizeTimeoutEvent);
- while true do
- begin
- case MsgWaitForMultipleObjects(2, WaitHandles, False, INFINITE, QS_SENDMESSAGE) of
- WAIT_OBJECT_0:
- break;
- WAIT_OBJECT_0+1:
- CheckSynchronize;
- WAIT_OBJECT_0+2:
- PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)
- end;
- end;
- end
- else
- WaitForSingleObject(ulong(FHandle), INFINITE);
- GetExitCodeThread(FHandle, DWord(Result));
- end;
|