tthread.inc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. {$include execd.inc}
  2. {$include execf.inc}
  3. {$include timerd.inc}
  4. {$include doslibd.inc}
  5. {$include doslibf.inc}
  6. {$include arosthreads.inc}
  7. function ThreadFunc(Data: Pointer): Pointer; cdecl;
  8. var
  9. LThread: TThread;
  10. LFreeOnTerminate: Boolean;
  11. ISuspended: Boolean;
  12. begin
  13. //Debugln('Enter ThreadFunc');
  14. Result := nil;
  15. LThread := TThread(Data);
  16. ISuspended := LThread.FInitialSuspended;
  17. if ISuspended then
  18. begin
  19. if not LThread.FTerminated then
  20. begin
  21. LockMutex(LThread.FSem);
  22. WaitCondition(LThread.FCond, LThread.FSem);
  23. UnlockMutex(LThread.FSem);
  24. end;
  25. end;
  26. //Sleep(1);
  27. if not LThread.FTerminated then
  28. begin
  29. //Debugln('Execute Thread');
  30. try
  31. LThread.Execute;
  32. except
  33. on E: Exception do
  34. begin
  35. //DebugLn('Exception in Thread '+ e.Classname + e.MEssage);
  36. LThread.FFatalException := TObject(AcquireExceptionObject);
  37. if E is EThreadDestroyCalled then
  38. LThread.FFreeOnTerminate := true;
  39. end;
  40. end;
  41. //Debugln('Back from Thread');
  42. //Sleep(1);
  43. end;
  44. LFreeOnTerminate := LThread.FreeOnTerminate;
  45. LThread.DoTerminate;
  46. LThread.FFinished := True;
  47. if LFreeOnTerminate then
  48. LThread.Free;
  49. //debugln('Finished Thread?, then what to do now?')
  50. end;
  51. procedure TThread.SysCreate(CreateSuspended: Boolean; const StackSize: SizeUInt);
  52. begin
  53. if not Assigned(AROSThreadStruct) then
  54. raise EThread.CreateFmt(SThreadCreateError, ['ThreadLib not found']);
  55. FSuspended := CreateSuspended;
  56. FInitialSuspended := CreateSuspended;
  57. // Mutex for suspend actions
  58. FSem := CreateMutex;
  59. FCond := CreateCondition;
  60. FHandle := AROSCreateThread(@ThreadFunc, Self, StackSize);
  61. FThreadID := FHandle;
  62. if FHandle = 0 then
  63. raise EThread.CreateFmt(SThreadCreateError, ['Cannot Create Thread']);
  64. // exception if Thread cannot be created
  65. FFatalException := nil;
  66. end;
  67. procedure TThread.SysDestroy;
  68. begin
  69. if FHandle <> 0 then
  70. begin
  71. if not FFinished then
  72. begin
  73. Terminate;
  74. if FSuspended then
  75. begin
  76. SignalCondition(FCond);
  77. Sleep(0);
  78. end;
  79. WaitFor;
  80. end;
  81. end;
  82. FHandle := 0;
  83. DestroyCondition(FCond);
  84. DestroyMutex(FSem);
  85. FFatalException := nil;
  86. end;
  87. procedure TThread.CallOnTerminate;
  88. begin
  89. FOnTerminate(Self);
  90. end;
  91. procedure TThread.DoTerminate;
  92. begin
  93. if Assigned(FOnTerminate) then
  94. Synchronize(@CallOnTerminate);
  95. end;
  96. function TThread.GetPriority: TThreadPriority;
  97. begin
  98. //
  99. end;
  100. procedure TThread.SetPriority(Value: TThreadPriority);
  101. begin
  102. //
  103. end;
  104. procedure TThread.SetSuspended(Value: Boolean);
  105. begin
  106. if Value <> FSuspended then
  107. if Value then
  108. Suspend
  109. else
  110. Resume;
  111. end;
  112. procedure TThread.Suspend;
  113. begin
  114. if FThreadID = GetCurrentThreadID then
  115. begin
  116. FSuspended := True;
  117. LockMutex(FSem);
  118. WaitCondition(FCond, FSem);
  119. UnlockMutex(FSem);
  120. end else
  121. Raise EThread.create('Suspending one thread from inside another one is unsupported (because it is unsafe and deadlock prone) by AROS');
  122. end;
  123. procedure TThread.Resume;
  124. begin
  125. if FSuspended then
  126. begin
  127. SignalCondition(FCond);
  128. Sleep(100);
  129. end;
  130. FSuspended := False;
  131. FInitialSuspended := False;
  132. end;
  133. procedure TThread.Terminate;
  134. begin
  135. FTerminated := True;
  136. end;
  137. function TThread.WaitFor: Integer;
  138. begin
  139. Result := 0;
  140. if (not FSuspended) and (FHandle <> 0) then
  141. begin
  142. Sleep(1);
  143. AROSWaitThread(FHandle);
  144. end;
  145. end;