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.

235 lines
6.0 KiB

  1. /***************************************************************************\
  2. *
  3. * File: Locks.inl
  4. *
  5. * History:
  6. * 3/30/2000: JStall: Created
  7. *
  8. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  9. *
  10. \***************************************************************************/
  11. #if !defined(BASE__Locks_inl__INCLUDED)
  12. #define BASE__Locks_inl__INCLUDED
  13. #pragma once
  14. #include "SimpleHeap.h"
  15. /***************************************************************************\
  16. *****************************************************************************
  17. *
  18. * Global Functions
  19. *
  20. *****************************************************************************
  21. \***************************************************************************/
  22. extern BOOL g_fThreadSafe;
  23. //------------------------------------------------------------------------------
  24. inline BOOL
  25. IsMultiThreaded()
  26. {
  27. return g_fThreadSafe;
  28. }
  29. #if 1
  30. //------------------------------------------------------------------------------
  31. inline long
  32. SafeIncrement(volatile long * pl)
  33. {
  34. if (g_fThreadSafe) {
  35. return InterlockedIncrement((long *) pl);
  36. } else {
  37. return ++(*pl);
  38. }
  39. }
  40. //------------------------------------------------------------------------------
  41. inline long
  42. SafeDecrement(volatile long * pl)
  43. {
  44. if (g_fThreadSafe) {
  45. return InterlockedDecrement((long *) pl);
  46. } else {
  47. return --(*pl);
  48. }
  49. }
  50. //------------------------------------------------------------------------------
  51. inline void
  52. SafeEnter(volatile CRITICAL_SECTION * pcs)
  53. {
  54. Assert(pcs);
  55. if (g_fThreadSafe) {
  56. EnterCriticalSection((CRITICAL_SECTION *) pcs);
  57. }
  58. }
  59. //------------------------------------------------------------------------------
  60. inline void
  61. SafeLeave(volatile CRITICAL_SECTION * pcs)
  62. {
  63. Assert(pcs);
  64. if (g_fThreadSafe) {
  65. LeaveCriticalSection((CRITICAL_SECTION *) pcs);
  66. }
  67. }
  68. #else
  69. #define SafeIncrement InterlockedIncrement
  70. #define SafeDecrement InterlockedDecrement
  71. #define SafeEnter EnterCriticalSection
  72. #define SafeLeave LeaveCriticalSection
  73. #endif
  74. /***************************************************************************\
  75. *****************************************************************************
  76. *
  77. * class CritLock
  78. *
  79. *****************************************************************************
  80. \***************************************************************************/
  81. //------------------------------------------------------------------------------
  82. inline
  83. CritLock::CritLock()
  84. {
  85. m_fThreadSafe = g_fThreadSafe;
  86. InitializeCriticalSectionAndSpinCount(&m_cs, 500);
  87. }
  88. //------------------------------------------------------------------------------
  89. inline
  90. CritLock::~CritLock()
  91. {
  92. DeleteCriticalSection(&m_cs);
  93. }
  94. //------------------------------------------------------------------------------
  95. inline void
  96. CritLock::Enter()
  97. {
  98. if (m_fThreadSafe) {
  99. SafeEnter(&m_cs);
  100. }
  101. }
  102. //------------------------------------------------------------------------------
  103. inline void
  104. CritLock::Leave()
  105. {
  106. if (m_fThreadSafe) {
  107. SafeLeave(&m_cs);
  108. }
  109. }
  110. //------------------------------------------------------------------------------
  111. inline BOOL
  112. CritLock::GetThreadSafe() const
  113. {
  114. return m_fThreadSafe;
  115. }
  116. //------------------------------------------------------------------------------
  117. inline void
  118. CritLock::SetThreadSafe(BOOL fThreadSafe)
  119. {
  120. m_fThreadSafe = fThreadSafe;
  121. }
  122. /***************************************************************************\
  123. *****************************************************************************
  124. *
  125. * class AutoCleanup
  126. *
  127. *****************************************************************************
  128. \***************************************************************************/
  129. //------------------------------------------------------------------------------
  130. template <class base>
  131. inline
  132. AutoCleanup<base>::~AutoCleanup()
  133. {
  134. DeleteAll();
  135. }
  136. //------------------------------------------------------------------------------
  137. template <class base>
  138. inline void
  139. AutoCleanup<base>::DeleteAll()
  140. {
  141. //
  142. // Once we start deleting items during shutdown, no new items should be
  143. // created, or they will not be destroyed.
  144. //
  145. // Currently, to help ensure this, we take the lock around the entire
  146. // shutdown. If another thread tries to add during this time, they get
  147. // blocked. However, they should not be doing this because this instance
  148. // is going away and the object will not have a chance to be cleaned up.
  149. //
  150. m_lock.Enter();
  151. while (!m_lstItems.IsEmpty()) {
  152. base * pItem = m_lstItems.UnlinkHead();
  153. placement_delete(pItem, base);
  154. HeapFree(GetProcessHeap(), 0, pItem);
  155. }
  156. m_lock.Leave();
  157. }
  158. //------------------------------------------------------------------------------
  159. template <class base>
  160. inline void
  161. AutoCleanup<base>::Link(base * pItem) {
  162. m_lock.Enter();
  163. m_lstItems.AddHead(pItem);
  164. m_lock.Leave();
  165. }
  166. //------------------------------------------------------------------------------
  167. template <class base>
  168. inline void
  169. AutoCleanup<base>::Delete(base * pItem)
  170. {
  171. AssertMsg(pItem != NULL, "Must specify a valid item");
  172. m_lock.Enter();
  173. m_lstItems.Unlink(pItem);
  174. m_lock.Leave();
  175. placement_delete(pItem, base);
  176. HeapFree(GetProcessHeap(), 0, pItem);
  177. }
  178. //------------------------------------------------------------------------------
  179. template <class base, class derived>
  180. inline derived *
  181. New(AutoCleanup<base> & lstItems)
  182. {
  183. derived * pItem = (derived *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(derived));
  184. if (pItem != NULL) {
  185. placement_new(pItem, derived);
  186. lstItems.Link(pItem);
  187. }
  188. return pItem;
  189. }
  190. #endif // BASE__Locks_inl__INCLUDED