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.

244 lines
7.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright(C) 1999 Microsoft Corporation all rights reserved.
  4. //
  5. // Module: workerthread.cpp
  6. //
  7. // Project: Chameleon
  8. //
  9. // Description: Generic Worker Thread Class Implementation
  10. //
  11. // Log:
  12. //
  13. // When Who What
  14. // ---- --- ----
  15. // 02/08/1999 TLP Initial Version
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. #include "stdafx.h"
  19. #include "workerthread.h"
  20. #include <process.h>
  21. //////////////////////////////////////////////////////////////////////////
  22. //
  23. // Function: Constructor
  24. //
  25. // Synopsis: Initialize the worker thread object
  26. //
  27. //////////////////////////////////////////////////////////////////////////
  28. CTheWorkerThread::CTheWorkerThread()
  29. {
  30. m_ThreadInfo.bExit = true;
  31. m_ThreadInfo.bSuspended = true;
  32. m_ThreadInfo.hWait = NULL;
  33. m_ThreadInfo.hExit = NULL;
  34. m_ThreadInfo.hThread = NULL;
  35. m_ThreadInfo.dwThreadId = 0;
  36. m_ThreadInfo.dwWaitInterval = 0;
  37. m_ThreadInfo.pfnCallback = NULL;
  38. }
  39. //////////////////////////////////////////////////////////////////////////
  40. //
  41. // Function: Destructor
  42. //
  43. // Synopsis: Syncronize the destruction of the worker thread with
  44. // the worker thread object.
  45. //
  46. //////////////////////////////////////////////////////////////////////////
  47. CTheWorkerThread::~CTheWorkerThread()
  48. {
  49. End(INFINITE, false);
  50. }
  51. //////////////////////////////////////////////////////////////////////////
  52. //
  53. // Function: StartThread
  54. //
  55. // Synopsis: Start the worker thread on its merry way
  56. //
  57. //////////////////////////////////////////////////////////////////////////
  58. bool CTheWorkerThread::Start(
  59. /*[in]*/ DWORD dwWaitInterval,
  60. /*[in]*/ Callback* pfnCallback
  61. )
  62. {
  63. _ASSERT( m_ThreadInfo.hThread == NULL && NULL != pfnCallback );
  64. bool bReturn = false;
  65. if ( NULL == m_ThreadInfo.hThread )
  66. {
  67. m_ThreadInfo.pfnCallback = pfnCallback;
  68. if ( dwWaitInterval )
  69. {
  70. m_ThreadInfo.dwWaitInterval = dwWaitInterval;
  71. m_ThreadInfo.bExit = false;
  72. }
  73. m_ThreadInfo.hWait = CreateEvent(NULL, TRUE, FALSE, NULL);
  74. if ( NULL != m_ThreadInfo.hWait )
  75. {
  76. m_ThreadInfo.hExit = CreateEvent(NULL, TRUE, FALSE, NULL);
  77. if ( NULL != m_ThreadInfo.hExit )
  78. {
  79. m_ThreadInfo.hThread = (HANDLE) _beginthreadex(
  80. NULL,
  81. 0,
  82. CTheWorkerThread::ThreadFunc,
  83. &m_ThreadInfo,
  84. 0,
  85. &m_ThreadInfo.dwThreadId
  86. );
  87. if ( m_ThreadInfo.hThread )
  88. {
  89. bReturn = true;
  90. }
  91. }
  92. }
  93. }
  94. return bReturn;
  95. }
  96. //////////////////////////////////////////////////////////////////////////
  97. //
  98. // Function: EndThread
  99. //
  100. // Synopsis: Attempt to end the worker thread
  101. //
  102. //////////////////////////////////////////////////////////////////////////
  103. bool CTheWorkerThread::End(
  104. /*[in]*/ DWORD dwTimeOut,
  105. /*[in]*/ bool bTerminateAfterWait
  106. )
  107. {
  108. bool bReturn = true;
  109. if ( m_ThreadInfo.hThread )
  110. {
  111. bReturn = false;
  112. // Set thread exiting flag to true (see ThreadFunc below...)
  113. m_ThreadInfo.bExit = true;
  114. // Resume our worker (if its currently suspended otherwise no-op)
  115. Resume();
  116. // Wake it up if its idle
  117. SetEvent(m_ThreadInfo.hWait);
  118. // Wait for it to exit
  119. if ( WAIT_OBJECT_0 != WaitForSingleObjectEx(m_ThreadInfo.hExit, dwTimeOut, FALSE) )
  120. {
  121. if ( bTerminateAfterWait )
  122. {
  123. _endthreadex((unsigned)m_ThreadInfo.hThread);
  124. // OK, we're without a thread now...
  125. CloseHandle(m_ThreadInfo.hWait);
  126. CloseHandle(m_ThreadInfo.hExit);
  127. CloseHandle(m_ThreadInfo.hThread);
  128. m_ThreadInfo.hThread = NULL;
  129. bReturn = true;
  130. }
  131. }
  132. else
  133. {
  134. // OK, we're without a thread now...
  135. CloseHandle(m_ThreadInfo.hWait);
  136. CloseHandle(m_ThreadInfo.hExit);
  137. CloseHandle(m_ThreadInfo.hThread);
  138. m_ThreadInfo.hThread = NULL;
  139. bReturn = true;
  140. }
  141. }
  142. return bReturn;
  143. }
  144. //////////////////////////////////////////////////////////////////////////
  145. //
  146. // Function: SuspendThread
  147. //
  148. // Synopsis: Suspend the worker thread
  149. //
  150. //////////////////////////////////////////////////////////////////////////
  151. void CTheWorkerThread::Suspend(void)
  152. {
  153. _ASSERT(m_ThreadInfo.hThread);
  154. m_ThreadInfo.bSuspended = true;
  155. ::SuspendThread(m_ThreadInfo.hThread);
  156. }
  157. //////////////////////////////////////////////////////////////////////////
  158. //
  159. // Function: ResumeThread
  160. //
  161. // Synopsis: Resume the worker thread
  162. //
  163. //////////////////////////////////////////////////////////////////////////
  164. void CTheWorkerThread::Resume(void)
  165. {
  166. _ASSERT(m_ThreadInfo.hThread);
  167. m_ThreadInfo.bSuspended = false;
  168. ::ResumeThread(m_ThreadInfo.hThread);
  169. }
  170. //////////////////////////////////////////////////////////////////////////
  171. //
  172. // Function: GetHandle()
  173. //
  174. // Synopsis: Return the thread handle
  175. //
  176. //////////////////////////////////////////////////////////////////////////
  177. HANDLE CTheWorkerThread::GetHandle(void)
  178. {
  179. return m_ThreadInfo.hThread;
  180. }
  181. //////////////////////////////////////////////////////////////////////////
  182. //
  183. // Function: ThreadFunc
  184. //
  185. // Synopsis: The worker thread function
  186. //
  187. //////////////////////////////////////////////////////////////////////////
  188. unsigned _stdcall CTheWorkerThread::ThreadFunc(LPVOID pThreadInfo)
  189. {
  190. // If One Shot Then
  191. // Do some work
  192. // Else
  193. // While not time to exit
  194. // Do some work
  195. // Go idle for the wait interval
  196. // End While
  197. // End While
  198. // End If
  199. // Set exit event (synchronize thread termination)
  200. SetThreadPriority(((PTHREADINFO)pThreadInfo)->hThread, THREAD_PRIORITY_HIGHEST);
  201. if ( ((PTHREADINFO)pThreadInfo)->bExit )
  202. {
  203. ((PTHREADINFO)pThreadInfo)->pfnCallback->DoCallback();
  204. }
  205. else
  206. {
  207. while ( ! ((PTHREADINFO)pThreadInfo)->bExit )
  208. {
  209. ((PTHREADINFO)pThreadInfo)->pfnCallback->DoCallback();
  210. WaitForSingleObjectEx(
  211. ((PTHREADINFO)pThreadInfo)->hWait,
  212. ((PTHREADINFO)pThreadInfo)->dwWaitInterval,
  213. FALSE
  214. );
  215. }
  216. }
  217. SetEvent(((PTHREADINFO)pThreadInfo)->hExit);
  218. return 0;
  219. }