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.

334 lines
7.0 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. reslock.cxx
  5. Abstract:
  6. Contains methods for RESOURCE_LOCK class
  7. Contents:
  8. RESOURCE_LOCK::Acquire()
  9. RESOURCE_LOCK::Release()
  10. Author:
  11. Richard L Firth (rfirth) 18-Jun-1996
  12. Revision History:
  13. 18-Jun-1996 rfirth
  14. Created
  15. --*/
  16. #include <wininetp.h>
  17. //
  18. // class members
  19. //
  20. #ifdef OLD_VERSION
  21. BOOL
  22. RESOURCE_LOCK::Acquire(
  23. IN BOOL bExclusiveMode
  24. )
  25. /*++
  26. Routine Description:
  27. Acquires the resource protected by this lock. Acquires for non-exclusive
  28. (read) or exclusive (write) ownership
  29. Arguments:
  30. bExclusiveMode - TRUE if we are acquiring the resource for exclusive
  31. (write) ownership
  32. Return Value:
  33. BOOL
  34. TRUE - resource is acquired
  35. FALSE - failed to acquire resource (timeout?)
  36. --*/
  37. {
  38. DEBUG_ENTER((DBG_RESLOCK,
  39. Bool,
  40. "RESOURCE_LOCK::Acquire",
  41. "%B",
  42. bExclusiveMode
  43. ));
  44. INET_ASSERT(this != NULL);
  45. //INET_ASSERT(IsInitialized());
  46. //INET_ASSERT(IsValid());
  47. if (!IsInitialized()) {
  48. DEBUG_LEAVE(FALSE);
  49. return FALSE;
  50. }
  51. BOOL acquired = TRUE;
  52. //EnterCriticalSection(&_CritSect);
  53. if (bExclusiveMode) {
  54. //
  55. // acquired for exclusive ownership (write access). Set the owning
  56. // thread id and wait for the last current reader to release. Note
  57. // that if we're being re-entered, EnterCriticalSection() has already
  58. // done the work of checking the thread id and updating re-entrancy
  59. // counts, so if its already not zero, we know it must be us
  60. //
  61. ++_WriteCount;
  62. if (_ThreadId == 0) {
  63. _ThreadId = GetCurrentThreadId();
  64. #if INET_DEBUG
  65. INET_ASSERT(_ThreadId != _ThreadIdReader);
  66. #endif
  67. acquired = Wait(_hWriteEvent);
  68. EnterCriticalSection(&_CritSect);
  69. } else {
  70. INET_ASSERT(_ThreadId == GetCurrentThreadId());
  71. }
  72. } else {
  73. //
  74. // don't allow re-entry if already held for exclusive access
  75. //
  76. INET_ASSERT(_ThreadId == 0);
  77. //
  78. // acquired for non-exclusive ownership (read access). Just increase
  79. // the number of active readers. If this is the first then inhibit the
  80. // writer
  81. //
  82. if (InterlockedIncrement(&_Readers) == 0) {
  83. #if INET_DEBUG
  84. if (_ThreadIdReader == 0) {
  85. _ThreadIdReader = GetCurrentThreadId();
  86. }
  87. #endif
  88. ResetEvent(_hWriteEvent);
  89. }
  90. //
  91. // reader doesn't need to keep hold of critical section
  92. //
  93. //LeaveCriticalSection(&_CritSect);
  94. }
  95. DEBUG_LEAVE(acquired);
  96. return acquired;
  97. }
  98. VOID
  99. RESOURCE_LOCK::Release(
  100. VOID
  101. )
  102. /*++
  103. Routine Description:
  104. Releases a resource previously acquired by RESOURCE_LOCK::Acquire()
  105. Arguments:
  106. None.
  107. Return Value:
  108. None.
  109. --*/
  110. {
  111. DEBUG_ENTER((DBG_RESLOCK,
  112. None,
  113. "RESOURCE_LOCK::Release",
  114. NULL
  115. ));
  116. INET_ASSERT(this != NULL);
  117. //INET_ASSERT(IsInitialized());
  118. //INET_ASSERT(IsValid());
  119. if (!IsInitialized()) {
  120. DEBUG_LEAVE(0);
  121. return;
  122. }
  123. if ((_ThreadId != 0) && (_ThreadId == GetCurrentThreadId())) {
  124. INET_ASSERT(_WriteCount > 0);
  125. if (--_WriteCount == 0) {
  126. //
  127. // we acquired _hWriteEvent; signal it to allow next writer to continue
  128. //
  129. SetEvent(_hWriteEvent);
  130. //
  131. // this resource no longer owned for exclusive access
  132. //
  133. _ThreadId = 0;
  134. }
  135. LeaveCriticalSection(&_CritSect);
  136. } else if (InterlockedDecrement(&_Readers) < 0) {
  137. INET_ASSERT(_Readers >= -1);
  138. //
  139. // we are last currently active reader; allow waiting writer to continue
  140. //
  141. #if INET_DEBUG
  142. if (_ThreadIdReader == GetCurrentThreadId()) {
  143. _ThreadIdReader = 0;
  144. }
  145. #endif
  146. SetEvent(_hWriteEvent);
  147. }
  148. DEBUG_LEAVE(0);
  149. }
  150. #else
  151. BOOL
  152. RESOURCE_LOCK::Acquire(
  153. IN BOOL bExclusiveMode
  154. )
  155. {
  156. DEBUG_ENTER((DBG_RESLOCK,
  157. Bool,
  158. "RESOURCE_LOCK::Acquire",
  159. "%B",
  160. bExclusiveMode
  161. ));
  162. if (!IsInitialized()) {
  163. DEBUG_LEAVE(FALSE);
  164. return FALSE;
  165. }
  166. if (bExclusiveMode) {
  167. do {
  168. DEBUG_PRINT(RESLOCK,
  169. INFO,
  170. ("Waiting on WriteEvent\n")
  171. );
  172. if (_ThreadId != GetCurrentThreadId()) {
  173. Wait(_hWriteEvent);
  174. }
  175. EnterCriticalSection(&_CritSect);
  176. INET_ASSERT((_ThreadId == 0) || (_ThreadId == GetCurrentThreadId()));
  177. if ((_Readers == -1)
  178. && ((_ThreadId == 0) || (_ThreadId == GetCurrentThreadId()))) {
  179. _ThreadId = GetCurrentThreadId();
  180. if (++_WriteCount == 1) {
  181. ResetEvent(_hWriteEvent);
  182. }
  183. break;
  184. }
  185. DEBUG_PRINT(RESLOCK,
  186. INFO,
  187. ("trying again\n")
  188. );
  189. LeaveCriticalSection(&_CritSect);
  190. } while ( 1 );
  191. } else {
  192. EnterCriticalSection(&_CritSect);
  193. if (++_Readers == 0) {
  194. DEBUG_PRINT(RESLOCK,
  195. INFO,
  196. ("Resetting WriteEvent\n")
  197. );
  198. ResetEvent(_hWriteEvent);
  199. }
  200. LeaveCriticalSection(&_CritSect);
  201. }
  202. DEBUG_LEAVE(TRUE);
  203. return TRUE;
  204. }
  205. VOID
  206. RESOURCE_LOCK::Release(
  207. VOID
  208. )
  209. {
  210. DEBUG_ENTER((DBG_RESLOCK,
  211. None,
  212. "RESOURCE_LOCK::Release",
  213. NULL
  214. ));
  215. if (IsInitialized()) {
  216. if (_ThreadId == GetCurrentThreadId()) {
  217. DEBUG_PRINT(RESLOCK,
  218. INFO,
  219. ("Clearing writer\n")
  220. );
  221. if (--_WriteCount == 0) {
  222. _ThreadId = 0;
  223. SetEvent(_hWriteEvent);
  224. }
  225. LeaveCriticalSection(&_CritSect);
  226. } else {
  227. EnterCriticalSection(&_CritSect);
  228. if (--_Readers == -1) {
  229. DEBUG_PRINT(RESLOCK,
  230. INFO,
  231. ("Setting WriteEvent\n")
  232. );
  233. SetEvent(_hWriteEvent);
  234. }
  235. LeaveCriticalSection(&_CritSect);
  236. }
  237. }
  238. DEBUG_LEAVE(0);
  239. }
  240. #endif // OLD_VERSION