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.

287 lines
5.8 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 2000.
  5. //
  6. // File: Worker.hxx
  7. //
  8. // Contents: Query queue
  9. //
  10. // History: 29-Dec-93 KyleP Created
  11. // 27-Sep-94 KyleP Generalized
  12. //
  13. //--------------------------------------------------------------------------
  14. #pragma once
  15. class CWorkQueue;
  16. class CWorkThread;
  17. //+---------------------------------------------------------------------------
  18. //
  19. // Class: PWorkItem
  20. //
  21. // Purpose: Pure virual class for work items
  22. //
  23. // History: 27-Sep-94 KyleP Created.
  24. //
  25. //----------------------------------------------------------------------------
  26. class PWorkItem
  27. {
  28. public:
  29. PWorkItem( LONGLONG eSigWorkItem ) : _eSigWorkItem(eSigWorkItem) {}
  30. virtual ~PWorkItem() {}
  31. //
  32. // Work function
  33. //
  34. virtual void DoIt( CWorkThread * pThread ) = 0;
  35. //
  36. // Refcounting
  37. //
  38. virtual void AddRef() = 0;
  39. virtual void Release() = 0;
  40. //
  41. // Linked list methods.
  42. //
  43. inline void Link( PWorkItem * pNext );
  44. inline PWorkItem * Next();
  45. protected:
  46. //-----------------------------------------------
  47. // This MUST be the first variable in this class.
  48. //-----------------------------------------------
  49. LONGLONG _eSigWorkItem;
  50. private:
  51. //
  52. // Link to next work item
  53. //
  54. PWorkItem * _pNext;
  55. };
  56. //+---------------------------------------------------------------------------
  57. //
  58. // Class: CWorkThread
  59. //
  60. // Purpose: Worker thread
  61. //
  62. // History: 27-Sep-94 KyleP Created.
  63. //
  64. //----------------------------------------------------------------------------
  65. class CWorkThread
  66. {
  67. public:
  68. CWorkThread( CWorkQueue & queue,
  69. CWorkThread * pNext,
  70. SHandle & hEvt1,
  71. SHandle & hEvt2
  72. );
  73. ~CWorkThread();
  74. void lokSetActiveItem( PWorkItem * pitem ) { _pitem = pitem; }
  75. PWorkItem * ActiveItem() { return _pitem; }
  76. void Reset()
  77. {
  78. vqDebugOut(( DEB_RESULTS, "Worker: RESET available\n" ));
  79. _evtQueryAvailable.Reset();
  80. }
  81. void Wakeup()
  82. {
  83. vqDebugOut(( DEB_ITRACE, "Worker: SET available\n" ));
  84. _evtQueryAvailable.Set();
  85. }
  86. void Wait();
  87. void Done();
  88. void WaitForCompletion( PWorkItem * pitem );
  89. void lokAbort() { _fAbort = TRUE; }
  90. BOOL lokShouldAbort() { return _fAbort; }
  91. void Link( CWorkThread * pNext ) { _pNext = pNext; }
  92. CWorkThread * Next() { return _pNext; }
  93. DWORD GetThreadId() { return _Thread.GetThreadId(); }
  94. HANDLE GetThreadHandle() { return _Thread.GetHandle(); }
  95. #ifdef CIEXTMODE
  96. void CiExtDump(void *ciExtSelf);
  97. #endif
  98. private:
  99. friend CWorkQueue;
  100. inline void AddRef();
  101. inline void Release();
  102. inline BOOL IsReferenced();
  103. static DWORD WINAPI WorkerThread( void * self );
  104. long _cRef;
  105. PWorkItem * _pitem; // Current item in work queue
  106. CWorkQueue & _queue; // Queue of work items
  107. CWorkThread * _pNext; // Next thread in llist
  108. BOOL _fAbort;
  109. CThread _Thread; // This thread
  110. // NOTE: these CEventSem's must be declared after the CThread!
  111. CEventSem _evtQueryAvailable; // Signaled when there is work
  112. CEventSem _evtDone; // Signaled when query is complete
  113. };
  114. //+---------------------------------------------------------------------------
  115. //
  116. // Class: CWorkQueue
  117. //
  118. // Purpose: Queue of pending work items
  119. //
  120. // History: 27-Sep-94 KyleP Created.
  121. //
  122. //----------------------------------------------------------------------------
  123. class CWorkQueue
  124. {
  125. public:
  126. enum WorkQueueType { workQueueQuery=0xa,
  127. workQueueRequest,
  128. workQueueFrmwrkClient };
  129. CWorkQueue( unsigned cThread, WorkQueueType workQueue );
  130. void Init()
  131. {
  132. _mtxLock.Init();
  133. RefreshParams( 2, 0 );
  134. _fInit = TRUE;
  135. }
  136. ~CWorkQueue();
  137. void Add( PWorkItem * pitem );
  138. void Remove( PWorkItem * pitem );
  139. inline unsigned Count();
  140. void RefreshParams( ULONG cMaxActiveThread, ULONG cMinIdleThreads );
  141. void Shutdown();
  142. inline void AddRef( CWorkThread * pThread );
  143. void AddRefWorkThreads();
  144. void ReleaseWorkThreads();
  145. void Release( CWorkThread * pThread );
  146. # ifdef CIEXTMODE
  147. void CiExtDump(void *ciExtSelf);
  148. # endif
  149. void GetWorkQueueRegParams( ULONG & cMaxActiveThreads,
  150. ULONG & cMinIdleThreads );
  151. private:
  152. friend class CWorkThread;
  153. void Remove( CWorkThread & Worker );
  154. void lokAddThread();
  155. void RemoveThreads();
  156. //
  157. // Link fields
  158. //
  159. PWorkItem * _pHead;
  160. PWorkItem * _pTail;
  161. unsigned _cQuery;
  162. //
  163. // Serialization
  164. //
  165. CMutexSem _mtxLock;
  166. //
  167. // Worker threads. Must be after semaphores.
  168. //
  169. CDynArray<CWorkThread> _apWorker;
  170. unsigned _cWorker;
  171. unsigned _cIdle;
  172. CWorkThread * _pIdle;
  173. BOOL _fInit;
  174. BOOL _fAbort;
  175. WorkQueueType _QueueType;
  176. ULONG _cMaxActiveThreads;
  177. ULONG _cMinIdleThreads;
  178. };
  179. inline unsigned CWorkQueue::Count()
  180. {
  181. return( _cQuery );
  182. }
  183. inline void CWorkQueue::AddRef( CWorkThread * pThread )
  184. {
  185. pThread->AddRef();
  186. }
  187. inline void PWorkItem::Link( PWorkItem * pNext )
  188. {
  189. _pNext = pNext;
  190. }
  191. inline PWorkItem * PWorkItem::Next()
  192. {
  193. return( _pNext );
  194. }
  195. inline void CWorkThread::AddRef()
  196. {
  197. InterlockedIncrement( &_cRef );
  198. }
  199. inline void CWorkThread::Release()
  200. {
  201. InterlockedDecrement( &_cRef );
  202. }
  203. inline BOOL CWorkThread::IsReferenced()
  204. {
  205. return _cRef != 0;
  206. }
  207. //
  208. // Global work queue. All queries will use threads from here.
  209. //
  210. extern CWorkQueue TheWorkQueue;