tthread.inc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2015 by Karoly Balogh,
  4. member of the Free Pascal development team.
  5. native TThread implementation for Amiga-like systems
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { Thread management routines }
  13. { Based on the Win32 version, but since that mostly just wraps to a stock
  14. ThreadManager, it was relatively straightforward to get this working,
  15. after we had a ThreadManager (AThreads) (KB) }
  16. procedure TThread.SysCreate(CreateSuspended: Boolean;
  17. const StackSize: SizeUInt);
  18. begin
  19. FSuspended := CreateSuspended;
  20. FInitialSuspended := CreateSuspended;
  21. { Always start in suspended state, will be resumed in AfterConstruction if necessary
  22. See Mantis #16884 }
  23. FHandle := BeginThread(nil, StackSize, @ThreadProc, pointer(self), CREATE_SUSPENDED,
  24. FThreadID);
  25. if FHandle = TThreadID(0) then
  26. raise EThread.CreateFmt(SThreadCreateError, ['Cannot create thread.']);
  27. FFatalException := nil;
  28. end;
  29. procedure TThread.SysDestroy;
  30. begin
  31. if FHandle<>0 then
  32. begin
  33. { Don't check Suspended. If the thread has been externally suspended (which is
  34. deprecated and strongly discouraged), it's better to deadlock here than
  35. to silently free the object and leave OS resources leaked. }
  36. if not FFinished {and not Suspended} then
  37. begin
  38. Terminate;
  39. { Allow the thread function to perform the necessary cleanup. Since
  40. we've just set Terminated flag, it won't call Execute. }
  41. if FInitialSuspended then
  42. Start;
  43. WaitFor;
  44. end;
  45. end;
  46. FFatalException.Free;
  47. FFatalException := nil;
  48. end;
  49. procedure TThread.CallOnTerminate;
  50. begin
  51. FOnTerminate(Self);
  52. end;
  53. procedure TThread.DoTerminate;
  54. begin
  55. if Assigned(FOnTerminate) then
  56. Synchronize(@CallOnTerminate);
  57. end;
  58. {const
  59. Priorities: array [TThreadPriority] of Integer =
  60. (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,
  61. THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,
  62. THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);}
  63. function TThread.GetPriority: TThreadPriority;
  64. var
  65. P: Integer;
  66. I: TThreadPriority;
  67. begin
  68. { P := GetThreadPriority(FHandle);
  69. Result := tpNormal;
  70. for I := Low(TThreadPriority) to High(TThreadPriority) do
  71. if Priorities[I] = P then Result := I;}
  72. end;
  73. procedure TThread.SetPriority(Value: TThreadPriority);
  74. begin
  75. // SetThreadPriority(FHandle, Priorities[Value]);
  76. end;
  77. procedure TThread.SetSuspended(Value: Boolean);
  78. begin
  79. if Value <> FSuspended then
  80. if Value then
  81. Suspend
  82. else
  83. Resume;
  84. end;
  85. procedure TThread.Suspend;
  86. begin
  87. { Unsupported, but lets have it... }
  88. FSuspended := True;
  89. SuspendThread(FHandle);
  90. end;
  91. procedure TThread.Resume;
  92. begin
  93. if ResumeThread(FHandle) = 1 then FSuspended := False;
  94. end;
  95. procedure TThread.Terminate;
  96. begin
  97. FTerminated := True;
  98. TerminatedSet;
  99. end;
  100. function TThread.WaitFor: Integer;
  101. begin
  102. if MainThreadID=GetCurrentThreadID then
  103. {
  104. FFinished is set after DoTerminate, which does a synchronize of OnTerminate,
  105. so make sure synchronize works (or indeed any other synchronize that may be
  106. in progress)
  107. }
  108. while not FFinished do
  109. CheckSynchronize(100);
  110. result:=WaitForThreadTerminate(FThreadID,0);
  111. end;