Leaked source code of windows server 2003
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.

249 lines
6.2 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (c) Microsoft Corporation, 1992 - 2002.
  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. //
  99. // For 32 bit, start with 16k commit for the stack to make sure we don't run out.
  100. // For 64 bit, start with 32k stack space, sink throwing an exception takes about
  101. // 12K of stack space.
  102. //
  103. #ifdef _WIN64
  104. ULONG ulStackSize = 32768;
  105. #else
  106. ULONG ulStackSize = 16384;
  107. #endif
  108. _handle = CreateThread( 0,
  109. ulStackSize,
  110. _ThreadFunction,
  111. (void *) this,
  112. fSuspend ? CREATE_SUSPENDED: 0,
  113. &_tid);
  114. if ( 0 == _handle )
  115. {
  116. THROW( CException() );
  117. }
  118. }
  119. //+---------------------------------------------------------------------------
  120. //
  121. // Member: CThread::~CThread
  122. //
  123. // Synopsis: Closes the handle
  124. //
  125. // History: 10-Nov-92 BartoszM Created
  126. //
  127. //----------------------------------------------------------------------------
  128. inline CThread::~CThread ()
  129. {
  130. Win4Assert( !_fSuspended || _fNeverRan );
  131. if ( !_fSuspended )
  132. WaitForDeath();
  133. CloseHandle( _handle );
  134. }
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Member: CThread::SetPriority
  138. //
  139. // Arguments: [nPriority] -- desired priority
  140. //
  141. // History: 27-Feb-92 BartoszM Created
  142. //
  143. //----------------------------------------------------------------------------
  144. inline void CThread::SetPriority ( int nPriority )
  145. {
  146. if ( !SetThreadPriority ( _handle, nPriority ))
  147. THROW( CException() );
  148. }
  149. //+---------------------------------------------------------------------------
  150. //
  151. // Member: CThread::Suspend
  152. //
  153. // Synopsis: Increments suspension count. Suspends the thread.
  154. //
  155. // Returns: suspended count
  156. //
  157. // History: 27-Feb-92 BartoszM Created
  158. //
  159. //----------------------------------------------------------------------------
  160. inline DWORD CThread::Suspend()
  161. {
  162. DWORD susCount = SuspendThread ( _handle );
  163. if ( 0xffffffff == susCount )
  164. THROW( CException() );
  165. return susCount;
  166. }
  167. //+---------------------------------------------------------------------------
  168. //
  169. // Member: CThread::Resume
  170. //
  171. // Synopsis: Decrements suspension count. Restarts if zero
  172. //
  173. // Returns: suspended count
  174. //
  175. // History: 27-Feb-92 BartoszM Created
  176. //
  177. //----------------------------------------------------------------------------
  178. inline DWORD CThread::Resume()
  179. {
  180. #if CIDBG == 1
  181. _fNeverRan = FALSE;
  182. #endif
  183. DWORD susCount = ResumeThread ( _handle );
  184. if ( 0xffffffff == susCount )
  185. THROW( CException() );
  186. _fSuspended = FALSE;
  187. return susCount;
  188. }
  189. //+---------------------------------------------------------------------------
  190. //
  191. // Member: CThread::WaitForDeath
  192. //
  193. // Synopsis: Block until thread dies.
  194. //
  195. // History: 24-Apr-92 KyleP Created
  196. //
  197. //----------------------------------------------------------------------------
  198. inline void CThread::WaitForDeath( DWORD msec )
  199. {
  200. if ( !_fSuspended )
  201. {
  202. DWORD res = WaitForSingleObject( _handle, msec );
  203. if ( WAIT_FAILED == res )
  204. THROW( CException() );
  205. }
  206. }