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.

242 lines
6.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: jpmgr.cxx
  7. //
  8. // Contents: CJobProcessorMgr class implementation.
  9. //
  10. // Classes: CJobProcessorMgr
  11. //
  12. // Functions: None.
  13. //
  14. // History: 25-Oct-95 MarkBl Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include "svc_core.hxx"
  20. // class CJobProcessorQueue
  21. //
  22. //+---------------------------------------------------------------------------
  23. //
  24. // Member: CJobProcessorQueue::~CJobProcessorQueue
  25. //
  26. // Synopsis: Destructor. Destruct job processor queue.
  27. //
  28. // Arguments: N/A
  29. //
  30. // Notes: None.
  31. //
  32. //----------------------------------------------------------------------------
  33. CJobProcessorQueue::~CJobProcessorQueue()
  34. {
  35. TRACE3(CJobProcessorQueue, ~CJobProcessorQueue);
  36. CJobProcessor * pjp;
  37. while ((pjp = (CJobProcessor *)CQueue::RemoveElement()) != NULL)
  38. {
  39. pjp->Release();
  40. }
  41. }
  42. // class CJobProcessorMgr
  43. //
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Member: CJobProcessorMgr::NewProcessor
  47. //
  48. // Synopsis: Create a new job processor object and add it to the queue.
  49. //
  50. // Arguments: None.
  51. //
  52. // Returns: S_OK -- Processor created successfully.
  53. // S_FALSE -- Service shutting down - ignore the request.
  54. // HRESULT -- On error.
  55. //
  56. // Notes: None.
  57. //
  58. //----------------------------------------------------------------------------
  59. HRESULT
  60. CJobProcessorMgr::NewProcessor(CJobProcessor ** ppjp)
  61. {
  62. TRACE3(CJobProcessorMgr, NewProcessor);
  63. CJobProcessor * pjp = new CJobProcessor;
  64. if (pjp == NULL)
  65. {
  66. CHECK_HRESULT(E_OUTOFMEMORY);
  67. return(E_OUTOFMEMORY);
  68. }
  69. HRESULT hr = pjp->Initialize();
  70. if (FAILED(hr))
  71. {
  72. delete pjp;
  73. CHECK_HRESULT(hr);
  74. return(hr);
  75. }
  76. //
  77. // Check if the service is shutting down.
  78. //
  79. if (IsServiceStopping())
  80. {
  81. //
  82. // Shutdown & release the new processor. With a successful call to
  83. // CJobProcessor::Initialize(), another thread now references pjp.
  84. // Shutdown instructs the thread to stop servicing the processor.
  85. //
  86. // NB : DO NOT delete pjp! The worker thread maintains a reference
  87. // until it has completed servicing it.
  88. //
  89. pjp->Shutdown();
  90. pjp->Release();
  91. return(S_FALSE);
  92. }
  93. EnterCriticalSection(&_csProcessorMgrCritSection);
  94. _JobProcessorQueue.AddElement(pjp);
  95. pjp->AddRef(); // For return below.
  96. LeaveCriticalSection(&_csProcessorMgrCritSection);
  97. *ppjp = pjp;
  98. return(S_OK);
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Member: CJobProcessorMgr::GarbageCollection
  103. //
  104. // Synopsis: Dequeue and release unused job processor objects. This member
  105. // is to be called occasionally by an idle thread to clean up the
  106. // queue. Idle worker threads which have expired call this member
  107. // upon termination, for example.
  108. //
  109. // Arguments: None.
  110. //
  111. // Notes: None.
  112. //
  113. //----------------------------------------------------------------------------
  114. void
  115. CJobProcessorMgr::GarbageCollection(void)
  116. {
  117. TRACE3(CJobProcessorMgr, GarbageCollection);
  118. CJobProcessor * pjp;
  119. EnterCriticalSection(&_csProcessorMgrCritSection);
  120. //
  121. // Evaluate all processors in the queue.
  122. //
  123. pjp = _JobProcessorQueue.GetFirstElement();
  124. while (pjp != NULL)
  125. {
  126. //
  127. // If a processor is idle and unreferenced, dequeue & release it.
  128. //
  129. // NB : CJobProcessor::Next() re-enters the critical section entered
  130. // above. This is OK, though, since the nesting occurs within
  131. // the same thread.
  132. // Also, the processor object will be AddRef()'d as a result of
  133. // Next(). The release logic undoes this.
  134. //
  135. CJobProcessor * pjpNext = pjp->Next();
  136. if (pjpNext != NULL)
  137. {
  138. pjpNext->Release(); // See note above.
  139. }
  140. if (pjp->IsIdle())
  141. {
  142. _JobProcessorQueue.RemoveElement(pjp);
  143. pjp->Release();
  144. }
  145. pjp = pjpNext;
  146. }
  147. LeaveCriticalSection(&_csProcessorMgrCritSection);
  148. }
  149. //+---------------------------------------------------------------------------
  150. //
  151. // Member: CJobProcessorMgr::GetFirstProcessor
  152. //
  153. // Synopsis: Return the first processor in the queue. This enables the
  154. // caller to enumerate the queue.
  155. //
  156. // Arguments: None.
  157. //
  158. // Notes: None.
  159. //
  160. //----------------------------------------------------------------------------
  161. CJobProcessor *
  162. CJobProcessorMgr::GetFirstProcessor(void)
  163. {
  164. TRACE3(CJobProcessorMgr, GetFirstProcessor);
  165. CJobProcessor * pjp;
  166. EnterCriticalSection(&_csProcessorMgrCritSection);
  167. pjp = _JobProcessorQueue.GetFirstElement();
  168. if (pjp != NULL)
  169. {
  170. pjp->AddRef();
  171. }
  172. LeaveCriticalSection(&_csProcessorMgrCritSection);
  173. return(pjp);
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Member: CJobProcessorMgr::Shutdown
  178. //
  179. // Synopsis: Shutdown & release all processors.
  180. //
  181. // Arguments: None.
  182. //
  183. // Notes: None.
  184. //
  185. //----------------------------------------------------------------------------
  186. void
  187. CJobProcessorMgr::Shutdown(void)
  188. {
  189. TRACE3(CJobProcessorMgr, Shutdown);
  190. CJobProcessor * pjp;
  191. EnterCriticalSection(&_csProcessorMgrCritSection);
  192. while ((pjp = _JobProcessorQueue.RemoveElement()) != NULL)
  193. {
  194. pjp->Shutdown();
  195. pjp->Release();
  196. }
  197. LeaveCriticalSection(&_csProcessorMgrCritSection);
  198. }