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.

236 lines
4.5 KiB

  1. //***************************************************************************
  2. //
  3. // File:
  4. //
  5. // Module: MS SNMP Provider
  6. //
  7. // Purpose:
  8. //
  9. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. /*
  13. * THREAD.CPP
  14. *
  15. * Implemenation of thread wrapper class.
  16. */
  17. #include <precomp.h>
  18. #include "csmir.h"
  19. #include "smir.h"
  20. #include "handles.h"
  21. #include "classfac.h"
  22. #include "thread.h"
  23. #include <textdef.h>
  24. #ifdef ICECAP_PROFILE
  25. #include <icapexp.h>
  26. #endif
  27. ThreadMap <CThread*, CThread*, CThread*,CThread*> CThread :: m_ThreadMap ;
  28. CThread :: CThread()
  29. {
  30. m_cRef=1;
  31. bWaiting=FALSE;
  32. m_ulThreadHandle = NULL;
  33. m_hThreadStopEvent= NULL;
  34. if(NULL == (m_hThreadStopEvent = CreateEvent(NULL, FALSE,
  35. FALSE, NULL)))
  36. {
  37. // WBEM_E_FAILED;
  38. }
  39. if(NULL == (m_hThreadSyncEvent = CreateEvent(NULL, FALSE,
  40. FALSE, NULL)))
  41. {
  42. // WBEM_E_FAILED;
  43. }
  44. m_ThreadMap.SetAt(this,this);
  45. }
  46. CThread::operator void*()
  47. {
  48. if((NULL != m_hThreadStopEvent) && (NULL != m_hThreadStopEvent))
  49. {
  50. //the thread has been created
  51. return this;
  52. }
  53. else
  54. {
  55. //the thread is invalid
  56. return (void*)NULL;
  57. }
  58. }
  59. ULONG CThread :: Release()
  60. {
  61. if (0!=--m_cRef)
  62. {
  63. return m_cRef;
  64. }
  65. delete this;
  66. return 0;
  67. }
  68. CThread:: ~CThread()
  69. {
  70. //clean-up
  71. if(m_hThreadStopEvent)
  72. {
  73. CloseHandle(m_hThreadStopEvent);
  74. }
  75. if(m_hThreadSyncEvent)
  76. {
  77. CloseHandle(m_hThreadSyncEvent);
  78. }
  79. m_ThreadMap.RemoveKey(this);
  80. }
  81. void __cdecl GenericThreadProc(void *arglist)
  82. {
  83. SetStructuredExceptionHandler seh;
  84. try
  85. {
  86. HRESULT hr = CoInitialize(NULL);
  87. if (SUCCEEDED(hr))
  88. {
  89. try
  90. {
  91. CThread *pThreadObject = (CThread*) arglist;
  92. if(S_OK == hr)
  93. {
  94. hr = pThreadObject->Process();
  95. if(SMIR_THREAD_DELETED != hr)
  96. {
  97. pThreadObject->Exit();
  98. }
  99. //else the thread has just been deleted
  100. }
  101. }
  102. catch(...)
  103. {
  104. CoUninitialize();
  105. throw;
  106. }
  107. CoUninitialize();
  108. }
  109. }
  110. catch(Structured_Exception e_SE)
  111. {
  112. return;
  113. }
  114. catch(Heap_Exception e_HE)
  115. {
  116. return;
  117. }
  118. catch(...)
  119. {
  120. return;
  121. }
  122. }
  123. #pragma warning (disable:4018)
  124. SCODE CThread :: Wait(DWORD timeout)
  125. {
  126. //create an array of wait events
  127. int iNumberOfEvents = m_UserEvents.GetCount()+1;
  128. HANDLE *lpHandles = new HANDLE[iNumberOfEvents];
  129. POSITION rNextPosition;
  130. UINT iLoop=0;
  131. for(rNextPosition=m_UserEvents.GetStartPosition();
  132. (NULL!=rNextPosition)&&(iLoop<iNumberOfEvents);iLoop++)
  133. {
  134. HANDLE lKey = 0;
  135. HANDLE pItem = NULL;
  136. m_UserEvents.GetNextAssoc(rNextPosition, lKey, pItem );
  137. lpHandles[iLoop] = pItem;
  138. }
  139. lpHandles[iNumberOfEvents-1] = m_hThreadStopEvent;
  140. //signal to the exit code that we are waiting
  141. bWaiting =TRUE;
  142. //wait for an event to fire
  143. DWORD dwResult = WaitForMultipleObjects(iNumberOfEvents,
  144. lpHandles, FALSE, timeout);
  145. bWaiting =FALSE;
  146. delete [] lpHandles;
  147. if(dwResult == iNumberOfEvents-1)
  148. {
  149. //thread stopped
  150. return WAIT_EVENT_TERMINATED;
  151. }
  152. else if (( ( dwResult<(iNumberOfEvents-1) ) ) ||
  153. (dwResult == WAIT_TIMEOUT) )
  154. {
  155. //a user event fired
  156. return dwResult;
  157. }
  158. else if ((WAIT_ABANDONED_0 >= dwResult)&&(dwResult<(WAIT_ABANDONED_0+iNumberOfEvents)))
  159. {
  160. //it gave up
  161. return (WAIT_EVENT_ABANDONED+(dwResult-WAIT_ABANDONED_0)-1);
  162. }
  163. //else the wait call failed
  164. return WAIT_EVENT_FAILED;
  165. }
  166. #pragma warning (default:4018)
  167. SCODE CThread :: Start()
  168. {
  169. //kick of the thread
  170. if(NULL == (void*)*this)
  171. {
  172. //creation failed
  173. return WBEM_E_FAILED;
  174. }
  175. if(NULL != m_ulThreadHandle)
  176. {
  177. //already running
  178. return THREAD_STARED;
  179. }
  180. if(-1==(m_ulThreadHandle = _beginthread (&GenericThreadProc, 0,((void*) this))))
  181. {
  182. //begin thread failed
  183. return WBEM_E_FAILED;
  184. }
  185. return S_OK;
  186. }
  187. SCODE CThread :: Stop ()
  188. {
  189. if(NULL==(void*)(*this)||(-1 == m_ulThreadHandle))
  190. {
  191. return WBEM_E_FAILED;
  192. }
  193. //terminate the thread if someone is waiting for it
  194. if(bWaiting)
  195. {
  196. SetEvent(m_hThreadStopEvent);
  197. WaitForSingleObject(m_hThreadSyncEvent,INFINITE);
  198. }
  199. //else just exit
  200. return S_OK;
  201. }
  202. void CThread :: ProcessDetach()
  203. {
  204. POSITION rNextPosition;
  205. UINT iLoop=0;
  206. for(rNextPosition=m_ThreadMap.GetStartPosition();
  207. NULL!=rNextPosition;iLoop++)
  208. {
  209. CThread *plKey = 0;
  210. CThread *pItem = NULL;
  211. m_ThreadMap.GetNextAssoc(rNextPosition, plKey, pItem );
  212. pItem->Release () ;
  213. }
  214. }