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.

440 lines
11 KiB

  1. #ifndef __THREAD_H
  2. #define __THREAD_H
  3. #include "Allocator.h"
  4. #include "TPQueue.h"
  5. #include "BasicTree.h"
  6. #include <lockst.h>
  7. /*
  8. * Forwards:
  9. *
  10. * WmiTask
  11. *
  12. * Description:
  13. *
  14. * Provides abstraction above heap allocation functions
  15. *
  16. * Version:
  17. *
  18. * Initial
  19. *
  20. * Last Changed:
  21. *
  22. * See Source Depot for change history
  23. *
  24. */
  25. template <class WmiKey> class WmiTask ;
  26. template <class WmiKey> class WmiThread ;
  27. /*
  28. * Class:
  29. *
  30. * WmiTask
  31. *
  32. * Description:
  33. *
  34. * Provides abstraction above heap allocation functions
  35. *
  36. * Version:
  37. *
  38. * Initial
  39. *
  40. * Last Changed:
  41. *
  42. * See Source Depot for change history
  43. *
  44. */
  45. template <class WmiKey>
  46. class WmiTask
  47. {
  48. friend WmiThread <WmiKey>;
  49. public:
  50. enum WmiTaskEnqueueType
  51. {
  52. e_WmiTask_Enqueue ,
  53. e_WmiTask_EnqueueAlertable ,
  54. e_WmiTask_EnqueueInterruptable
  55. } ;
  56. enum WmiTaskState
  57. {
  58. e_WmiTask_UnInitialized ,
  59. e_WmiTask_Initialized ,
  60. e_WmiTask_EnQueued ,
  61. e_WmiTask_DeQueued
  62. } ;
  63. private:
  64. LONG m_ReferenceCount ;
  65. WmiAllocator &m_Allocator ;
  66. wchar_t *m_Name ;
  67. wchar_t *m_CompletionName ;
  68. HANDLE m_Event ;
  69. HANDLE m_CompletionEvent ;
  70. WmiStatusCode m_InitializationStatusCode ;
  71. WmiTaskEnqueueType m_EnqueueType ;
  72. WmiTaskState m_TaskState ;
  73. private:
  74. void SetTaskState ( WmiTaskState a_TaskState ) { m_TaskState = a_TaskState ; }
  75. public:
  76. WmiTask (
  77. WmiAllocator &a_Allocator ,
  78. const wchar_t *a_Name = NULL ,
  79. const wchar_t *a_CompletionName = NULL
  80. ) ;
  81. WmiTask (
  82. WmiAllocator &a_Allocator ,
  83. HANDLE a_Event ,
  84. HANDLE a_CompletionEvent ,
  85. const wchar_t *a_Name = NULL ,
  86. const wchar_t *a_CompletionName = NULL
  87. ) ;
  88. virtual ~WmiTask () ;
  89. virtual ULONG STDMETHODCALLTYPE AddRef () ;
  90. virtual ULONG STDMETHODCALLTYPE Release () ;
  91. virtual WmiStatusCode Initialize () ;
  92. virtual WmiStatusCode UnInitialize () ;
  93. virtual WmiStatusCode Process ( WmiThread <WmiKey> &a_Thread ) ;
  94. virtual WmiStatusCode Exec () ;
  95. virtual WmiStatusCode Complete () ;
  96. virtual WmiStatusCode Wait ( const ULONG &a_Timeout = INFINITE ) ;
  97. virtual WmiStatusCode WaitInterruptable ( const ULONG &a_Timeout = INFINITE ) ;
  98. virtual WmiStatusCode WaitAlertable ( const ULONG &a_Timeout = INFINITE ) ;
  99. wchar_t *GetName () { return m_Name ; }
  100. wchar_t *GetCompletionName () { return m_CompletionName ; }
  101. HANDLE GetEvent () { return m_Event ; }
  102. HANDLE GetCompletionEvent () { return m_CompletionEvent ; }
  103. WmiAllocator &GetAllocator () { return m_Allocator ; }
  104. WmiTaskState TaskState () { return m_TaskState ; }
  105. WmiTaskEnqueueType EnqueuedAs () { return m_EnqueueType ; }
  106. void EnqueueAs ( WmiTaskEnqueueType a_EnqueueType ) { m_EnqueueType = a_EnqueueType ; }
  107. } ;
  108. /*
  109. * Class:
  110. *
  111. * WmiThread
  112. *
  113. * Description:
  114. *
  115. * Provides abstraction above heap allocation functions
  116. *
  117. * Version:
  118. *
  119. * Initial
  120. *
  121. * Last Changed:
  122. *
  123. * See Source Depot for change history
  124. *
  125. */
  126. template <class WmiKey>
  127. class WmiThread
  128. {
  129. friend class WmiTask <WmiKey> ;
  130. public:
  131. class QueueKey
  132. {
  133. public:
  134. WmiKey m_Key ;
  135. INT64 m_Tick ;
  136. QueueKey () { ; } ;
  137. QueueKey ( const INT64 &a_Tick , const WmiKey &a_Key ) :
  138. m_Key ( a_Key ) ,
  139. m_Tick ( a_Tick )
  140. {
  141. }
  142. ~QueueKey () { ; }
  143. INT64 GetTick () { return m_Tick ; }
  144. void SetTick ( const INT64 &a_Tick ) { m_Tick = a_Tick ; }
  145. WmiKey &GetKey () { return m_Key ; }
  146. friend bool operator == ( const QueueKey &a_Arg1 , const QueueKey &a_Arg2 )
  147. {
  148. LONG t_Compare ;
  149. if ( ( t_Compare = CompareElement ( a_Arg1.m_Key , a_Arg2.m_Key ) ) == 0 )
  150. {
  151. t_Compare = CompareElement ( a_Arg1.m_Tick , a_Arg2.m_Tick ) ;
  152. }
  153. return t_Compare == 0 ? true : false ;
  154. }
  155. friend bool operator < ( const QueueKey &a_Arg1 , const QueueKey &a_Arg2 )
  156. {
  157. LONG t_Compare ;
  158. if ( ( t_Compare = CompareElement ( a_Arg1.m_Key , a_Arg2.m_Key ) ) == 0 )
  159. {
  160. t_Compare = CompareElement ( a_Arg1.m_Tick , a_Arg2.m_Tick ) ;
  161. }
  162. return t_Compare < 0 ? true : false ;
  163. }
  164. } ;
  165. typedef WmiBasicTree <WmiTask <WmiKey> * , WmiThread <WmiKey> *> TaskContainer ;
  166. typedef typename TaskContainer :: Iterator TaskContainerIterator ;
  167. typedef WmiBasicTree <ULONG , WmiThread <WmiKey> *> ThreadContainer ;
  168. typedef typename ThreadContainer :: Iterator ThreadContainerIterator ;
  169. typedef WmiTreePriorityQueue <QueueKey,WmiTask <WmiKey> *> QueueContainer ;
  170. typedef typename WmiTreePriorityQueue <QueueKey,WmiTask <WmiKey> *> :: Iterator QueueContainerIterator ;
  171. private:
  172. static ULONG ThreadProc ( void *a_Thread ) ;
  173. static ThreadContainer *s_ThreadContainer ;
  174. static TaskContainer *s_TaskContainer ;
  175. static CriticalSection s_CriticalSection ;
  176. static LONG s_InitializeReferenceCount ;
  177. INT64 m_Key;
  178. LONG m_ReferenceCount ;
  179. LONG m_InternalReferenceCount ;
  180. CriticalSection m_CriticalSection ;
  181. WmiStatusCode m_InitializationStatusCode ;
  182. // Determine change in queue state.
  183. HANDLE m_Initialized ;
  184. HANDLE m_QueueChange ;
  185. HANDLE m_Terminate ;
  186. // All allocations done via allocator
  187. WmiAllocator &m_Allocator ;
  188. // Useful debug information
  189. wchar_t *m_Name ;
  190. HANDLE m_Thread ;
  191. ULONG m_Identifier ;
  192. // Timeout period for internal event dispatch
  193. ULONG m_Timeout ;
  194. // Stack Size
  195. DWORD m_StackSize ;
  196. // All runnable tasks are placed in the queue in priority order,
  197. // as task are executed, task can re-schedule itself, otherwise it is discarded.
  198. // Priority is based on key compounded with insertion order ( ticks ), this implies
  199. // tasks with same key are scheduled in FIFO order.
  200. WmiTreePriorityQueue <QueueKey,WmiTask <WmiKey> *> m_TaskQueue ;
  201. // All runnable tasks are placed in the queue in priority order,
  202. // as task are executed, task can re-schedule itself, otherwise it is discarded.
  203. // Priority is based on key compounded with insertion order ( ticks ), this implies
  204. // tasks with same key are scheduled in FIFO order.
  205. WmiTreePriorityQueue <QueueKey,WmiTask <WmiKey> *> m_InterruptableTaskQueue ;
  206. // Alertable events are placed on the queue, as event is signalled they are transferred onto
  207. // the regular queue where they are priority dispatched based on priority as inserted.
  208. WmiTreePriorityQueue <QueueKey,WmiTask <WmiKey> *> m_AlertableTaskQueue ;
  209. // a_EventCount [in] = Number of Predefined Dispatchable Events
  210. static WmiStatusCode Static_Dispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  211. static WmiStatusCode Static_Dispatch ( WmiTask <WmiKey> &a_Task , WmiThread <WmiKey> &a_Thread , const ULONG &a_Timeout ) ;
  212. WmiStatusCode Dispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  213. WmiStatusCode Wait ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  214. static WmiStatusCode Static_InterruptableDispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  215. static WmiStatusCode Static_InterruptableDispatch ( WmiTask <WmiKey> &a_Task , WmiThread <WmiKey> &a_Thread , const ULONG &a_Timeout ) ;
  216. WmiStatusCode InterruptableDispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  217. WmiStatusCode InterruptableWait ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  218. WmiStatusCode Execute ( QueueContainer &a_Queue , QueueContainer &t_EnQueue ) ;
  219. WmiStatusCode ShuffleTask (
  220. const HANDLE &a_Event
  221. ) ;
  222. WmiStatusCode FillHandleTable (
  223. HANDLE *a_HandleTable ,
  224. ULONG &a_Capacity
  225. ) ;
  226. static WmiStatusCode Static_AlertableDispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  227. static WmiStatusCode Static_AlertableDispatch ( WmiTask <WmiKey> &a_Task , WmiThread <WmiKey> &a_Thread , const ULONG &a_Timeout ) ;
  228. WmiStatusCode AlertableDispatch ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  229. WmiStatusCode AlertableWait ( WmiTask <WmiKey> &a_Task , const ULONG &a_Timeout ) ;
  230. // Dispatch code
  231. WmiStatusCode ThreadDispatch () ;
  232. WmiStatusCode ThreadWait () ;
  233. WmiStatusCode CreateThread () ;
  234. static WmiThread *GetThread () ;
  235. static WmiThread *GetServicingThread ( WmiTask <WmiKey> &a_Task ) ;
  236. HANDLE GetTerminateHandle () ;
  237. public:
  238. WmiThread (
  239. WmiAllocator &a_Allocator ,
  240. const wchar_t *a_Name = NULL ,
  241. ULONG a_Timeout = INFINITE ,
  242. DWORD a_StackSize = 0
  243. ) ;
  244. virtual ~WmiThread () ;
  245. virtual ULONG STDMETHODCALLTYPE AddRef () ;
  246. virtual ULONG STDMETHODCALLTYPE Release () ;
  247. virtual ULONG STDMETHODCALLTYPE InternalAddRef () ;
  248. virtual ULONG STDMETHODCALLTYPE InternalRelease () ;
  249. virtual WmiStatusCode Initialize_Callback () { return e_StatusCode_Success ; } ;
  250. virtual WmiStatusCode UnInitialize_Callback () { return e_StatusCode_Success ; } ;
  251. virtual void CallBackRelease () {} ;
  252. virtual WmiStatusCode Initialize ( const ULONG &a_Timeout = INFINITE ) ;
  253. virtual WmiStatusCode UnInitialize () ;
  254. virtual WmiStatusCode PostShutdown () ;
  255. virtual WmiStatusCode TimedOut () ;
  256. // Queue a task to be executed immediately, a thread that calls a task procedure that
  257. // executes a Wait or MsgWait will receive an indication in Queue status will not execute
  258. // newly queued tasks.
  259. virtual WmiStatusCode EnQueue (
  260. const WmiKey &a_Key ,
  261. WmiTask <WmiKey> &a_Task
  262. ) ;
  263. virtual WmiStatusCode EnQueueAlertable (
  264. const WmiKey &a_Key ,
  265. WmiTask <WmiKey> &a_Task
  266. ) ;
  267. // Queue a task to be executed immediately, a thread that calls a task procedure that
  268. // executes a Wait or MsgWait will receive an indication of Queue status change will execute
  269. // newly queued tasks. This is used for STA based execution where we need to interrupt the wait
  270. // to execute a dependant request.
  271. //
  272. virtual WmiStatusCode EnQueueInterruptable (
  273. const WmiKey &a_Key ,
  274. WmiTask <WmiKey> &a_Task
  275. ) ;
  276. virtual WmiStatusCode DeQueue (
  277. const WmiKey &a_Key ,
  278. WmiTask <WmiKey> &a_Task
  279. ) ;
  280. virtual WmiStatusCode DeQueueAlertable (
  281. const WmiKey &a_Key ,
  282. WmiTask <WmiKey> &a_Task
  283. ) ;
  284. virtual WmiStatusCode DeQueueInterruptable (
  285. const WmiKey &a_Key ,
  286. WmiTask <WmiKey> &a_Task
  287. ) ;
  288. wchar_t *GetName () { return m_Name ; }
  289. ULONG GetIdentifier () { return m_Identifier ; }
  290. HANDLE GetHandle () { return m_Thread ; }
  291. ULONG GetTimeout () { return m_Timeout ; }
  292. DWORD GetStackSize () { return m_StackSize ; }
  293. void SetTimeout ( const ULONG &a_Timeout ) { m_Timeout = a_Timeout ; }
  294. void SetStackSize ( const DWORD &a_StackSize ) { m_StackSize = a_StackSize ; }
  295. HANDLE GetTerminationEvent () { return m_Terminate ; }
  296. HANDLE GetQueueChangeEvent () { return m_QueueChange ; }
  297. WmiAllocator &GetAllocator () { return m_Allocator ; }
  298. static WmiStatusCode Static_Initialize ( WmiAllocator &a_Allocator ) ;
  299. static WmiStatusCode Static_UnInitialize ( WmiAllocator &a_Allocator ) ;
  300. } ;
  301. #include <Thread.cpp>
  302. #include <tpwrap.h>
  303. #endif __THREAD_H