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.

299 lines
5.2 KiB

  1. /*++
  2. rwnew.h
  3. This file defines several variations of Reader/Writer locks
  4. with different properties regarding handles used, and other
  5. implementation details.
  6. Also defined are some variations of CRITICAL_SECTIONS which use
  7. fewer or no handles.
  8. --*/
  9. #ifndef _RWNEW_H
  10. #define _RWNEW_H
  11. #ifdef _RW_IMPLEMENTATION_
  12. #define _RW_INTERFACE_ __declspec( dllexport )
  13. #else
  14. #define _RW_INTERFACE_ __declspec( dllimport )
  15. #endif
  16. #pragma warning( disable:4251 )
  17. #include <limits.h>
  18. #include "lockq.h"
  19. #include "rwintrnl.h"
  20. class _RW_INTERFACE_ CCritSection {
  21. private :
  22. //
  23. // Handle of thread owning the lock !
  24. //
  25. HANDLE m_hOwner ;
  26. //
  27. // Count of Recursive Calls
  28. //
  29. long m_RecursionCount ;
  30. //
  31. // Count used to see who gets the lock next !
  32. //
  33. long m_lock ;
  34. //
  35. // Queue of waiting threads
  36. //
  37. CSingleReleaseQueue m_queue ;
  38. //
  39. // Copying of these objects is not allowed !!!!
  40. //
  41. CCritSection( CCritSection& ) ;
  42. CCritSection& operator=( CCritSection& ) ;
  43. public :
  44. #ifdef DEBUG
  45. DWORD m_dwThreadOwner ;
  46. #endif
  47. //
  48. // Construct a critical section object
  49. //
  50. CCritSection( ) :
  51. m_queue( FALSE ),
  52. m_hOwner( INVALID_HANDLE_VALUE ),
  53. m_RecursionCount( 0 ),
  54. m_lock( -1 ) {
  55. }
  56. //
  57. // Acquire the critical section
  58. //
  59. void
  60. Enter(
  61. CWaitingThread& myself
  62. ) ;
  63. //
  64. // Another version which acquires the critical section -
  65. // creates its own CWaitingThread object !
  66. //
  67. void
  68. Enter() ;
  69. //
  70. // REturns TRUE if the lock is available right now !
  71. //
  72. BOOL
  73. TryEnter(
  74. CWaitingThread& myself
  75. ) ;
  76. //
  77. // Returns TRUE if we can get the lock right now !
  78. //
  79. BOOL
  80. TryEnter() {
  81. CWaitingThread myself ;
  82. return TryEnter( myself ) ;
  83. }
  84. //
  85. // Release the critical section !
  86. //
  87. void
  88. Leave() ;
  89. } ;
  90. //
  91. // This version of critical section is more like an event - doesn't
  92. // care who releases locks - and doesn't handle recursive grabs !
  93. //
  94. class _RW_INTERFACE_ CSimpleCritSection {
  95. private :
  96. //
  97. // Count used to see who gets the lock next !
  98. //
  99. long m_lock ;
  100. //
  101. // Queue of waiting threads
  102. //
  103. CSingleReleaseQueue m_queue ;
  104. //
  105. // Copying of these objects is not allowed !!!!
  106. //
  107. CSimpleCritSection( CCritSection& ) ;
  108. CSimpleCritSection& operator=( CCritSection& ) ;
  109. public :
  110. //
  111. // Construct a critical section object
  112. //
  113. CSimpleCritSection( ) :
  114. m_queue( FALSE ),
  115. m_lock( -1 ) {
  116. }
  117. //
  118. // Acquire the critical section
  119. //
  120. void
  121. Enter(
  122. CWaitingThread& myself
  123. ) ;
  124. //
  125. // Another version which acquires the critical section -
  126. // creates its own CWaitingThread object !
  127. //
  128. void
  129. Enter() ;
  130. //
  131. // REturns TRUE if the lock is available right now !
  132. //
  133. BOOL
  134. TryEnter(
  135. CWaitingThread& myself
  136. ) ;
  137. //
  138. // Returns TRUE if we can get the lock right now !
  139. //
  140. BOOL
  141. TryEnter() {
  142. CWaitingThread myself ;
  143. return TryEnter( myself ) ;
  144. }
  145. //
  146. // Release the critical section !
  147. //
  148. void
  149. Leave() ;
  150. } ;
  151. //
  152. // Another class which tries to create Reader/Write locks with
  153. // no handles !!
  154. //
  155. class _RW_INTERFACE_ CShareLockNH {
  156. private :
  157. //
  158. // Lock grabbed by writers to have exclusive access
  159. //
  160. CSimpleCritSection m_lock ;
  161. //
  162. // Number of readers who have grabbed the Read Lock -
  163. // Negative if a writer is waiting !
  164. //
  165. volatile long m_cReadLock ;
  166. //
  167. // Number of Readers who have left the lock since a
  168. // writer tried to grab it !
  169. //
  170. volatile long m_cOutReaders ;
  171. //
  172. // Number of readers who are entering the lock after
  173. // being blocked !!!
  174. //
  175. volatile long m_cOutAcquiringReaders ;
  176. //
  177. // Handle that all the readers who are waiting try to grab !
  178. //
  179. volatile HANDLE m_hWaitingReaders ;
  180. //
  181. // Handle that the single writer waiting for the lock is trying
  182. // to grab !
  183. //
  184. volatile HANDLE m_hWaitingWriters ;
  185. void inline
  186. WakeReaders() ;
  187. //
  188. // The internal work of ShareLock - does a lot more of the stuff required
  189. // when a writer is present !!!
  190. //
  191. void
  192. ShareLockInternal() ;
  193. //
  194. // The internal work of ShareLock - does a lot more of the stuff required
  195. // when a writer is present !!!
  196. //
  197. void
  198. ShareUnlockInternal() ;
  199. public :
  200. //
  201. // Construction of CShareLockNH() objects always succeeds and there
  202. // are no error cases !
  203. //
  204. CShareLockNH() ;
  205. //
  206. // Grab the lock Shared - other threads may pass through ShareLock() as well
  207. //
  208. void ShareLock() ;
  209. //
  210. // Releases the lock - if we are the last reader to leave writers may
  211. // start to enter the lock !
  212. //
  213. void ShareUnlock() ;
  214. //
  215. // Grab the lock Exclusively - no other readers or writers may enter !!
  216. //
  217. void ExclusiveLock() ;
  218. //
  219. // Release the Exclusive Locks - if there are readers waiting they
  220. // will enter before other waiting writers !
  221. //
  222. void ExclusiveUnlock() ;
  223. //
  224. // Convert an ExclusiveLock to a Shared - this cannot fail !
  225. //
  226. void ExclusiveToShared() ;
  227. //
  228. // Convert a Shared Lock to an Exclusive one - this can fail - returns
  229. // TRUE if successfull !
  230. //
  231. BOOL SharedToExclusive() ;
  232. BOOL TryShareLock() ;
  233. BOOL TryExclusiveLock() ;
  234. } ;
  235. #endif // _RWNEW_H_