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.

241 lines
5.7 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: workman.cxx
  7. //
  8. // Contents: Manages a queue of work items and supports aborting during
  9. // shutdown.
  10. //
  11. // History: 12-23-96 srikants Created
  12. //
  13. //----------------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include <workman.hxx>
  17. CWorkManager::~CWorkManager()
  18. {
  19. AbortWorkItems();
  20. }
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Member: CWorkManager::RemoveFromWorkList
  24. //
  25. // Synopsis: Removes the given work item from the worklist.
  26. //
  27. // Arguments: [pItem] - Item to be removed from the work list.
  28. //
  29. // History: 2-26-96 srikants Created
  30. //
  31. // Notes:
  32. //
  33. //----------------------------------------------------------------------------
  34. void CWorkManager::RemoveFromWorkList( CFwAsyncWorkItem * pItem )
  35. {
  36. Win4Assert( 0 != pItem );
  37. CLock lock(_mutex);
  38. //
  39. // If the item has already been removed from the list
  40. // (by an abort thread), don't remove it here.
  41. //
  42. if ( !pItem->IsSingle() )
  43. {
  44. _workList.RemoveFromList( pItem );
  45. pItem->Close();
  46. pItem->Release();
  47. }
  48. }
  49. //+---------------------------------------------------------------------------
  50. //
  51. // Member: CWorkManager::AddToWorkList
  52. //
  53. // Synopsis: Adds the given work item to the work list.
  54. //
  55. // Arguments: [pItem] - Item to be added to the work list.
  56. //
  57. // History: 2-26-96 srikants Created
  58. //
  59. // Notes: It is up to the caller to get the work item scheduled.
  60. //
  61. //----------------------------------------------------------------------------
  62. void CWorkManager::AddToWorkList( CFwAsyncWorkItem * pItem )
  63. {
  64. Win4Assert( 0 != pItem );
  65. CLock lock(_mutex);
  66. if ( _fShutdown )
  67. {
  68. ciDebugOut(( DEB_ITRACE, "AddToWorkList - Shutdown Initiated\n" ));
  69. pItem->Close();
  70. pItem->Abort();
  71. }
  72. else
  73. {
  74. pItem->AddRef();
  75. _workList.Push( pItem );
  76. }
  77. }
  78. //+---------------------------------------------------------------------------
  79. //
  80. // Member: CWorkManager::AbortWorkItems
  81. //
  82. // Synopsis: Aborts async workitems in the work list.
  83. //
  84. // History: 2-26-96 srikants Created
  85. //
  86. // Notes:
  87. //
  88. //----------------------------------------------------------------------------
  89. void CWorkManager::AbortWorkItems()
  90. {
  91. // ====================================================
  92. CLock lock(_mutex);
  93. _fShutdown = TRUE;
  94. for ( CFwAsyncWorkItem * pItem = _workList.RemoveLast();
  95. 0 != pItem;
  96. pItem = _workList.RemoveLast() )
  97. {
  98. pItem->Close();
  99. pItem->Abort();
  100. pItem->Release();
  101. }
  102. // ====================================================
  103. }
  104. //+---------------------------------------------------------------------------
  105. //
  106. // Member: ~ctor of CFwAsyncWorkItem
  107. //
  108. // Synopsis: Initializes the double link element and refcounts the
  109. // CCiManager.
  110. //
  111. // Arguments: [ciManager] -
  112. //
  113. // History: 2-27-96 srikants Created
  114. //
  115. // Notes:
  116. //
  117. //----------------------------------------------------------------------------
  118. CFwAsyncWorkItem::CFwAsyncWorkItem( CWorkManager & workMan,
  119. CWorkQueue & workQueue ) :
  120. PWorkItem( esigFwAsyncWorkItem ),
  121. _workMan(workMan),
  122. _workQueue(workQueue),
  123. _refCount(1),
  124. _fAbort(FALSE),
  125. _fOnWorkQueue(FALSE)
  126. {
  127. CDoubleLink::Close();
  128. _workMan.AddRef();
  129. }
  130. //+---------------------------------------------------------------------------
  131. //
  132. // Member: CFwAsyncWorkItem::~CFwAsyncWorkItem
  133. //
  134. // Synopsis: Releases the ciManager.
  135. //
  136. // History: 2-27-96 srikants Created
  137. //
  138. // Notes:
  139. //
  140. //----------------------------------------------------------------------------
  141. CFwAsyncWorkItem::~CFwAsyncWorkItem()
  142. {
  143. _workMan.Release();
  144. }
  145. //+---------------------------------------------------------------------------
  146. //
  147. // Member: CFwAsyncWorkItem::Done
  148. //
  149. // Synopsis: Removes from the ciManager list of workitems. This is called
  150. // at the end of the "DoIt()" method.
  151. //
  152. // History: 2-26-96 srikants Created
  153. //
  154. // Notes:
  155. //
  156. //----------------------------------------------------------------------------
  157. void CFwAsyncWorkItem::Done()
  158. {
  159. Win4Assert( _refCount > 0 );
  160. Win4Assert( !_fOnWorkQueue );
  161. _workMan.RemoveFromWorkList( this );
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Member: CFwAsyncWorkItem::AddToWorkQueue
  166. //
  167. // Synopsis: Adds the item to the work queue.
  168. //
  169. // History: 2-26-96 srikants Created
  170. //
  171. // Notes:
  172. //
  173. //----------------------------------------------------------------------------
  174. void CFwAsyncWorkItem::AddToWorkQueue()
  175. {
  176. CLock lock(_mutex);
  177. Win4Assert( !_fOnWorkQueue );
  178. if ( !_fAbort )
  179. {
  180. Win4Assert( !IsSingle() ); // it must be on the ciManager list
  181. _fOnWorkQueue = TRUE;
  182. _workQueue.Add( this );
  183. }
  184. }
  185. //+---------------------------------------------------------------------------
  186. //
  187. // Member: CFwAsyncWorkItem::Abort
  188. //
  189. // Synopsis: Aborts the work item. Removes it from the work queue if
  190. // necessary.
  191. //
  192. // History: 2-26-96 srikants Created
  193. //
  194. // Notes:
  195. //
  196. //----------------------------------------------------------------------------
  197. void CFwAsyncWorkItem::Abort()
  198. {
  199. //
  200. // It must be removed from the ciManager list before calling
  201. // abort.
  202. //
  203. CLock lock(_mutex);
  204. Win4Assert( IsSingle() );
  205. _fAbort = TRUE;
  206. if ( _fOnWorkQueue )
  207. {
  208. _fOnWorkQueue = FALSE;
  209. _workQueue.Remove(this);
  210. }
  211. }