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.

268 lines
4.9 KiB

  1. #ifndef __LOCKS_H__
  2. #define __LOCKS_H__
  3. #include <windows.h>
  4. #include <dothrow.h>
  5. # pragma once
  6. const bool THROW_LOCK = true;
  7. const bool NOTHROW_LOCK = false;
  8. class CriticalSection
  9. {
  10. public:
  11. CriticalSection (bool can_throw , DWORD count = 0 );
  12. // Initialize the CRITICAL_SECTION.
  13. ~CriticalSection (void);
  14. // Implicitly destroy the CRITICAL_SECTION.
  15. bool close (void);
  16. // dummy call
  17. bool acquire (void);
  18. // Acquire lock ownership ( block if necessary).
  19. bool tryacquire (void);
  20. // Conditionally acquire lock ( non blocking ). Returns
  21. // false on failure
  22. bool release (void);
  23. // Release lock
  24. bool acquire_read (void);
  25. bool acquire_write (void);
  26. bool tryacquire_read (void);
  27. bool tryacquire_write (void);
  28. bool valid() const { return initialized_;}
  29. const CRITICAL_SECTION &lock (void) const;
  30. // Return the underlying mutex.
  31. void dump( void ) const ;
  32. private:
  33. CRITICAL_SECTION lock_;
  34. bool initialized_;
  35. bool can_throw_;
  36. void raise_exception();
  37. private:
  38. // = Prevent assignment and initialization.
  39. void operator= (CriticalSection &);
  40. CriticalSection (const CriticalSection &);
  41. };
  42. template <class Lock>
  43. bool SleepAndLock( Lock& lock, int timeout )
  44. {
  45. if (lock.valid())
  46. for (;!lock.locked();)
  47. {
  48. Sleep(timeout);
  49. lock.acquire();
  50. }
  51. return lock.locked();
  52. }
  53. inline
  54. CriticalSection::CriticalSection (bool can_throw,DWORD count):initialized_(false),can_throw_(can_throw)
  55. {
  56. #ifdef _WIN32_WINNT
  57. #if _WIN32_WINNT > 0x0400
  58. initialized_ = (InitializeCriticalSectionAndSpinCount(&lock_,count))?true:false;
  59. #else
  60. __try
  61. {
  62. InitializeCriticalSection(&lock_);
  63. initialized_ = true;
  64. }
  65. __except(GetExceptionCode() == STATUS_NO_MEMORY)
  66. {
  67. }
  68. #endif
  69. #else
  70. __try
  71. {
  72. InitializeCriticalSection(&lock_);
  73. initialized_ = true;
  74. }
  75. __except(GetExceptionCode() == STATUS_NO_MEMORY)
  76. {
  77. }
  78. #endif
  79. if (initialized_ != true)
  80. raise_exception();
  81. };
  82. inline
  83. CriticalSection::~CriticalSection ()
  84. {
  85. if (initialized_)
  86. DeleteCriticalSection(&lock_);
  87. }
  88. inline void
  89. CriticalSection::raise_exception()
  90. {
  91. if (can_throw_)
  92. throw CX_MemoryException();
  93. };
  94. inline bool
  95. CriticalSection::acquire(void)
  96. {
  97. return acquire_write();
  98. };
  99. inline bool
  100. CriticalSection::acquire_read(void)
  101. {
  102. return acquire_write();
  103. };
  104. #ifndef STATUS_POSSIBLE_DEADLOCK
  105. #define STATUS_POSSIBLE_DEADLOCK (0xC0000194L)
  106. #endif /*STATUS_POSSIBLE_DEADLOCK */
  107. DWORD POLARITY BreakOnDbgAndRenterLoop(void);
  108. inline bool
  109. CriticalSection::acquire_write(void)
  110. {
  111. if (initialized_)
  112. {
  113. __try {
  114. EnterCriticalSection(&lock_);
  115. } __except((STATUS_POSSIBLE_DEADLOCK == GetExceptionCode())? BreakOnDbgAndRenterLoop():EXCEPTION_CONTINUE_SEARCH) {
  116. }
  117. return true;
  118. }
  119. return false;
  120. };
  121. inline bool
  122. CriticalSection::release(void)
  123. {
  124. if (initialized_)
  125. {
  126. LeaveCriticalSection(&lock_);
  127. return true;
  128. }
  129. return false;
  130. }
  131. inline bool
  132. CriticalSection::tryacquire()
  133. {
  134. return tryacquire_write();
  135. };
  136. inline bool
  137. CriticalSection::tryacquire_read()
  138. {
  139. return tryacquire_write();
  140. };
  141. inline bool
  142. CriticalSection::tryacquire_write()
  143. {
  144. __try
  145. {
  146. #ifdef _WIN32_WINNT
  147. #if _WIN32_WINNT > 0x0400
  148. return TRUE == TryEnterCriticalSection(&lock_);
  149. #else
  150. return false;
  151. #endif
  152. #else
  153. return false;
  154. #endif
  155. }
  156. __except(GetExceptionCode() == STATUS_NO_MEMORY)
  157. {
  158. };
  159. return false;
  160. };
  161. inline bool
  162. CriticalSection::close()
  163. {
  164. return false;
  165. };
  166. #ifdef _WIN32_WINNT
  167. #if _WIN32_WINNT > 0x0400
  168. class ReaderWriter
  169. {
  170. struct RTL_RESOURCE {
  171. struct RTL_RESOURCE_DEBUG;
  172. RTL_CRITICAL_SECTION CriticalSection;
  173. HANDLE SharedSemaphore;
  174. ULONG NumberOfWaitingShared;
  175. HANDLE ExclusiveSemaphore;
  176. ULONG NumberOfWaitingExclusive;
  177. LONG NumberOfActive;
  178. HANDLE ExclusiveOwnerThread;
  179. ULONG Flags; // See RTL_RESOURCE_FLAG_ equates below.
  180. RTL_RESOURCE_DEBUG* DebugInfo;
  181. };
  182. public:
  183. ReaderWriter (bool can_throw);
  184. ~ReaderWriter (void);
  185. bool close (void);
  186. bool acquire (void);
  187. bool tryacquire (void);
  188. bool release (void);
  189. // Release lock
  190. bool acquire_read (void);
  191. bool acquire_write (void);
  192. bool tryacquire_read (void);
  193. bool tryacquire_write (void);
  194. void upgrade();
  195. void downgrade();
  196. bool valid() const { return initialized_;}
  197. const ReaderWriter &lock (void) const;
  198. // Return the underlying mutex.
  199. void dump( void ) const;
  200. private:
  201. RTL_RESOURCE lock_;
  202. bool initialized_;
  203. bool can_throw_;
  204. void raise_exception();
  205. private:
  206. // = Prevent assignment and initialization.
  207. void operator= (ReaderWriter &);
  208. ReaderWriter (const ReaderWriter &);
  209. };
  210. inline void
  211. ReaderWriter::raise_exception()
  212. {
  213. if (can_throw_)
  214. throw CX_MemoryException();
  215. };
  216. #endif
  217. #endif
  218. #endif