Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
5.8 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (c) Microsoft Corporation, 1992-1999
  5. //
  6. // File: THRD32.HXX
  7. //
  8. // Contents: Windows thread abstraction
  9. //
  10. // Classes: CThread
  11. //
  12. // History: 27-Feb-92 BartoszM Created
  13. //
  14. // Notes: Thread object
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Class: CThread
  20. //
  21. // Purpose: Encapsulation of thread
  22. //
  23. // History: 27-Feb-92 BartoszM Created
  24. //
  25. //----------------------------------------------------------------------------
  26. class CThread
  27. {
  28. public:
  29. inline CThread ( LPTHREAD_START_ROUTINE pFun,
  30. void* pData,
  31. BOOL fSuspend=FALSE );
  32. inline ~CThread ();
  33. inline void SetPriority( int nPriority );
  34. inline DWORD Suspend();
  35. inline DWORD Resume ();
  36. inline BOOL IsRunning() { return !_fSuspended; }
  37. inline void WaitForDeath(DWORD dwMilliseconds = 0xFFFFFFFF);
  38. const HANDLE GetHandle() const { return _handle; }
  39. DWORD GetThreadId() const { return _tid; }
  40. private:
  41. static DWORD _ThreadFunction( void * pv )
  42. {
  43. DWORD dw = 0;
  44. //
  45. // Don't display system errors in worker threads -- the
  46. // service needs to keep running always.
  47. //
  48. CNoErrorMode noErrors;
  49. CTranslateSystemExceptions translate;
  50. TRY
  51. {
  52. CThread & me = * (CThread *) pv;
  53. dw = me._pFun( me._pData );
  54. }
  55. CATCH( CException, e )
  56. {
  57. //
  58. // We should never get here, since each thread is responsible
  59. // for dealing with exceptions and leaving cleanly.
  60. //
  61. Win4Assert( !"CThread top-level exception not handled properly" );
  62. }
  63. END_CATCH
  64. return dw;
  65. }
  66. HANDLE _handle;
  67. DWORD _tid;
  68. LPTHREAD_START_ROUTINE _pFun;
  69. void * _pData;
  70. BOOL _fSuspended;
  71. #if CIDBG == 1
  72. BOOL _fNeverRan;
  73. #endif
  74. };
  75. //+---------------------------------------------------------------------------
  76. //
  77. // Member: CThread::CThread
  78. //
  79. // Synopsis: Creates a new thread
  80. //
  81. // Arguments: [pFun] -- entry point
  82. // [obj] -- pointer passed to thread
  83. // [fSuspend] -- start suspended
  84. //
  85. // History: 27-Feb-92 BartoszM Created
  86. //
  87. //----------------------------------------------------------------------------
  88. inline CThread::CThread( LPTHREAD_START_ROUTINE pFun,
  89. void * obj,
  90. BOOL fSuspend )
  91. : _pFun( pFun ),
  92. _pData( obj ),
  93. _fSuspended( fSuspend )
  94. {
  95. #if CIDBG == 1
  96. _fNeverRan = fSuspend;
  97. #endif
  98. // Start with 16k commit for the stack to make sure we don't run out.
  99. _handle = CreateThread( 0,
  100. 4096 * 4,
  101. _ThreadFunction,
  102. (void *) this,
  103. fSuspend ? CREATE_SUSPENDED: 0,
  104. &_tid);
  105. if ( 0 == _handle )
  106. {
  107. THROW( CException() );
  108. }
  109. }
  110. //+---------------------------------------------------------------------------
  111. //
  112. // Member: CThread::~CThread
  113. //
  114. // Synopsis: Closes the handle
  115. //
  116. // History: 10-Nov-92 BartoszM Created
  117. //
  118. //----------------------------------------------------------------------------
  119. inline CThread::~CThread ()
  120. {
  121. Win4Assert( !_fSuspended || _fNeverRan );
  122. if ( !_fSuspended )
  123. WaitForDeath();
  124. CloseHandle( _handle );
  125. }
  126. //+---------------------------------------------------------------------------
  127. //
  128. // Member: CThread::SetPriority
  129. //
  130. // Arguments: [nPriority] -- desired priority
  131. //
  132. // History: 27-Feb-92 BartoszM Created
  133. //
  134. //----------------------------------------------------------------------------
  135. inline void CThread::SetPriority ( int nPriority )
  136. {
  137. if ( !SetThreadPriority ( _handle, nPriority ))
  138. THROW( CException() );
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Member: CThread::Suspend
  143. //
  144. // Synopsis: Increments suspension count. Suspends the thread.
  145. //
  146. // Returns: suspended count
  147. //
  148. // History: 27-Feb-92 BartoszM Created
  149. //
  150. //----------------------------------------------------------------------------
  151. inline DWORD CThread::Suspend()
  152. {
  153. DWORD susCount = SuspendThread ( _handle );
  154. if ( 0xffffffff == susCount )
  155. THROW( CException() );
  156. return susCount;
  157. }
  158. //+---------------------------------------------------------------------------
  159. //
  160. // Member: CThread::Resume
  161. //
  162. // Synopsis: Decrements suspension count. Restarts if zero
  163. //
  164. // Returns: suspended count
  165. //
  166. // History: 27-Feb-92 BartoszM Created
  167. //
  168. //----------------------------------------------------------------------------
  169. inline DWORD CThread::Resume()
  170. {
  171. #if CIDBG == 1
  172. _fNeverRan = FALSE;
  173. #endif
  174. DWORD susCount = ResumeThread ( _handle );
  175. if ( 0xffffffff == susCount )
  176. THROW( CException() );
  177. _fSuspended = FALSE;
  178. return susCount;
  179. }
  180. //+---------------------------------------------------------------------------
  181. //
  182. // Member: CThread::WaitForDeath
  183. //
  184. // Synopsis: Block until thread dies.
  185. //
  186. // History: 24-Apr-92 KyleP Created
  187. //
  188. //----------------------------------------------------------------------------
  189. inline void CThread::WaitForDeath( DWORD msec )
  190. {
  191. if ( !_fSuspended )
  192. {
  193. DWORD res = WaitForSingleObject( _handle, msec );
  194. if ( WAIT_FAILED == res )
  195. THROW( CException() );
  196. }
  197. }