tthread.inc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. {
  2. $Id$
  3. This file is part of the Free Component Library (FCL)
  4. Copyright (c) 1999-2003 by the Free Pascal development team
  5. Netware TThread implementation
  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. type
  13. PThreadRec=^TThreadRec;
  14. TThreadRec=record
  15. thread : TThread;
  16. next : PThreadRec;
  17. end;
  18. var
  19. ThreadRoot : PThreadRec;
  20. ThreadsInited : boolean;
  21. // MainThreadID: longint;
  22. Const
  23. ThreadCount: longint = 0;
  24. {function ThreadSelf:TThread;
  25. var
  26. hp : PThreadRec;
  27. sp : longint;
  28. begin
  29. sp:=SPtr;
  30. hp:=ThreadRoot;
  31. while assigned(hp) do
  32. begin
  33. if (sp<=hp^.Thread.FStackPointer) and
  34. (sp>(hp^.Thread.FStackPointer-hp^.Thread.FStackSize)) then
  35. begin
  36. Result:=hp^.Thread;
  37. exit;
  38. end;
  39. hp:=hp^.next;
  40. end;
  41. Result:=nil;
  42. end;}
  43. procedure InitThreads;
  44. begin
  45. ThreadRoot:=nil;
  46. ThreadsInited:=true;
  47. end;
  48. procedure DoneThreads;
  49. var
  50. hp : PThreadRec;
  51. begin
  52. while assigned(ThreadRoot) do
  53. begin
  54. ThreadRoot^.Thread.Destroy;
  55. hp:=ThreadRoot;
  56. ThreadRoot:=ThreadRoot^.Next;
  57. dispose(hp);
  58. end;
  59. ThreadsInited:=false;
  60. end;
  61. procedure AddThread(t:TThread);
  62. var
  63. hp : PThreadRec;
  64. begin
  65. { Need to initialize threads ? }
  66. if not ThreadsInited then
  67. InitThreads;
  68. { Put thread in the linked list }
  69. new(hp);
  70. hp^.Thread:=t;
  71. hp^.next:=ThreadRoot;
  72. ThreadRoot:=hp;
  73. inc(ThreadCount, 1);
  74. end;
  75. procedure RemoveThread(t:TThread);
  76. var
  77. lasthp,hp : PThreadRec;
  78. begin
  79. hp:=ThreadRoot;
  80. lasthp:=nil;
  81. while assigned(hp) do
  82. begin
  83. if hp^.Thread=t then
  84. begin
  85. if assigned(lasthp) then
  86. lasthp^.next:=hp^.next
  87. else
  88. ThreadRoot:=hp^.next;
  89. dispose(hp);
  90. exit;
  91. end;
  92. lasthp:=hp;
  93. hp:=hp^.next;
  94. end;
  95. Dec(ThreadCount, 1);
  96. if ThreadCount = 0 then DoneThreads;
  97. end;
  98. { TThread }
  99. function ThreadProc(args:pointer): Integer;cdecl;
  100. var
  101. FreeThread: Boolean;
  102. Thread : TThread absolute args;
  103. begin
  104. try
  105. Thread.Execute;
  106. except
  107. Thread.FFatalException := TObject(AcquireExceptionObject);
  108. end;
  109. FreeThread := Thread.FFreeOnTerminate;
  110. Result := Thread.FReturnValue;
  111. Thread.FFinished := True;
  112. Thread.DoTerminate;
  113. if FreeThread then
  114. Thread.Free;
  115. EndThread(Result);
  116. end;
  117. constructor TThread.Create(CreateSuspended: Boolean);
  118. var
  119. Flags: Integer;
  120. begin
  121. inherited Create;
  122. AddThread(self);
  123. FSuspended := CreateSuspended;
  124. { Create new thread }
  125. FHandle := BeginThread (@ThreadProc,self);
  126. if FSuspended then Suspend;
  127. FThreadID := FHandle;
  128. //IsMultiThread := TRUE; {already set by systhrds}
  129. FFatalException := nil;
  130. end;
  131. destructor TThread.Destroy;
  132. begin
  133. if not FFinished {and not Suspended} then
  134. begin
  135. if Suspended then ResumeThread (FHandle); {netware can not kill a thread}
  136. Terminate;
  137. WaitFor;
  138. end;
  139. if FHandle <> -1 then
  140. KillThread (FHandle); {something went wrong, kill the thread (not possible on netware)}
  141. FFatalException.Free;
  142. FFatalException := nil;
  143. inherited Destroy;
  144. RemoveThread(self);
  145. end;
  146. procedure TThread.CallOnTerminate;
  147. begin
  148. FOnTerminate(Self);
  149. end;
  150. procedure TThread.DoTerminate;
  151. begin
  152. if Assigned(FOnTerminate) then
  153. Synchronize(@CallOnTerminate);
  154. end;
  155. const
  156. Priorities: array [TThreadPriority] of Integer =
  157. (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,
  158. THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,
  159. THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);
  160. function TThread.GetPriority: TThreadPriority;
  161. var
  162. P: Integer;
  163. I: TThreadPriority;
  164. begin
  165. P := ThreadGetPriority(FHandle);
  166. Result := tpNormal;
  167. for I := Low(TThreadPriority) to High(TThreadPriority) do
  168. if Priorities[I] = P then Result := I;
  169. end;
  170. procedure TThread.SetPriority(Value: TThreadPriority);
  171. begin
  172. ThreadSetPriority(FHandle, Priorities[Value]);
  173. end;
  174. {does not make sense for netware}
  175. procedure TThread.Synchronize(Method: TThreadMethod);
  176. begin
  177. {$ifndef netware}
  178. FSynchronizeException := nil;
  179. FMethod := Method;
  180. { SendMessage(ThreadWindow, CM_EXECPROC, 0, Longint(Self)); }
  181. {$warning Synchronize needs implementation}
  182. if Assigned(FSynchronizeException) then
  183. raise FSynchronizeException;
  184. {$endif}
  185. end;
  186. procedure TThread.SetSuspended(Value: Boolean);
  187. begin
  188. if Value <> FSuspended then
  189. if Value then
  190. Suspend
  191. else
  192. Resume;
  193. end;
  194. procedure TThread.Suspend;
  195. begin
  196. SuspendThread (FHandle);
  197. FSuspended := true;
  198. end;
  199. procedure TThread.Resume;
  200. begin
  201. ResumeThread (FHandle);
  202. FSuspended := False;
  203. end;
  204. procedure TThread.Terminate;
  205. begin
  206. FTerminated := True;
  207. ThreadSwitch;
  208. end;
  209. function TThread.WaitFor: Integer;
  210. begin
  211. Result := WaitForThreadTerminate (FHandle,0);
  212. if Result = 0 then
  213. FHandle := -1;
  214. end;
  215. {
  216. $Log$
  217. Revision 1.1 2003-10-06 21:01:06 peter
  218. * moved classes unit to rtl
  219. Revision 1.3 2003/10/06 17:06:55 florian
  220. * applied Johannes Berg's patch for exception handling in threads
  221. Revision 1.2 2003/03/27 17:14:27 armin
  222. * more platform independent thread routines, needs to be implemented for unix
  223. Revision 1.1 2003/03/25 17:56:19 armin
  224. * first fcl implementation for netware
  225. Revision 1.7 2002/12/18 20:44:36 peter
  226. * use fillchar to clear sigset
  227. Revision 1.6 2002/09/07 15:15:27 peter
  228. * old logs removed and tabs fixed
  229. }