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.

191 lines
3.8 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. reslock.hxx
  5. Abstract:
  6. Contains RESOURCE_LOCK class
  7. Author:
  8. Richard L Firth (rfirth) 18-Jun-1996
  9. Revision History:
  10. 18-Jun-1996 rfirth
  11. Created
  12. --*/
  13. //
  14. // manifests
  15. //
  16. #if INET_DEBUG
  17. #define DEFAULT_RESOURCE_LOCK_TIMEOUT 30000 // 30 seconds
  18. #else
  19. #define DEFAULT_RESOURCE_LOCK_TIMEOUT INFINITE
  20. #endif
  21. //
  22. // class definition
  23. //
  24. class RESOURCE_LOCK {
  25. private:
  26. //
  27. // _Initialized - TRUE when the critical section & event have been created
  28. //
  29. BOOL _Initialized;
  30. //
  31. // _WriteCount - number of times writer has re-entered
  32. //
  33. LONG _WriteCount;
  34. //
  35. // _ThreadId - ID of the owning writer thread
  36. //
  37. DWORD _ThreadId;
  38. //
  39. // _Readers - number of reader threads. Used as a switch in concert with
  40. // InterlockedIncrement/InterlockedDecrement: -1 => 0 means this is the
  41. // first reader, and we reset the writer wait event; 0 => -1 means this is
  42. // the last reader and we set the writer wait event
  43. //
  44. LONG _Readers;
  45. //
  46. // _Timeout - number of milliseconds to wait for one of the event handles
  47. //
  48. DWORD _Timeout;
  49. //
  50. // _hWriteEvent - signalled when the last reader thread exits. At this time
  51. // the writer thread has exclusive access
  52. //
  53. HANDLE _hWriteEvent;
  54. //
  55. // _CritSect - used to serialize access. Writer keeps this until Releas()ed.
  56. // Readers just keep it long enough to update _Readers variable
  57. //
  58. CCritSec _CritSect;
  59. //
  60. // Wait - wait for an event to become signalled
  61. //
  62. BOOL Wait(HANDLE hEvent) {
  63. DWORD error = WaitForSingleObject(hEvent, _Timeout);
  64. if (error == WAIT_OBJECT_0) {
  65. return TRUE;
  66. } else {
  67. DEBUG_PRINT(UTIL,
  68. ERROR,
  69. ("RESOURCE_LOCK::Wait(): WaitForSingleObject() returns %d\n",
  70. error
  71. ));
  72. if (error == WAIT_TIMEOUT) {
  73. error = ERROR_WINHTTP_TIMEOUT;
  74. } else {
  75. error = ERROR_WINHTTP_INTERNAL_ERROR;
  76. }
  77. SetLastError(error);
  78. return FALSE;
  79. }
  80. }
  81. VOID SetTimeout(DWORD Timeout) {
  82. _Timeout = Timeout;
  83. }
  84. DWORD GetTimeout(VOID) const {
  85. return _Timeout;
  86. }
  87. public:
  88. RESOURCE_LOCK() {
  89. _WriteCount = 0;
  90. _ThreadId = 0;
  91. _Readers = -1;
  92. _Timeout = DEFAULT_RESOURCE_LOCK_TIMEOUT;
  93. _hWriteEvent = NULL;
  94. _Initialized = FALSE;
  95. }
  96. ~RESOURCE_LOCK() {
  97. INET_ASSERT(_WriteCount == 0);
  98. INET_ASSERT(_ThreadId == 0);
  99. INET_ASSERT(_Readers == -1);
  100. if (_hWriteEvent != NULL) {
  101. CloseHandle(_hWriteEvent);
  102. }
  103. }
  104. VOID Initialize(VOID) {
  105. _WriteCount = 0;
  106. _ThreadId = 0;
  107. _Readers = -1;
  108. _Timeout = DEFAULT_RESOURCE_LOCK_TIMEOUT;
  109. _CritSect.Init();
  110. //
  111. // _hWriteEvent is an auto-reset, initially-signalled event
  112. //
  113. _hWriteEvent = CreateEvent(NULL, FALSE, TRUE, NULL);
  114. if (_CritSect.IsInitialized() && _hWriteEvent != NULL)
  115. _Initialized = TRUE;
  116. else
  117. _Initialized = FALSE;
  118. }
  119. BOOL IsInitialized(VOID) const {
  120. return _Initialized;
  121. }
  122. BOOL IsValid(VOID) const {
  123. return (_hWriteEvent != NULL) ? TRUE : FALSE;
  124. }
  125. BOOL
  126. Acquire(
  127. IN BOOL bExclusiveMode = FALSE
  128. );
  129. BOOL AcquireExclusive(VOID) {
  130. return Acquire(TRUE);
  131. }
  132. VOID
  133. Release(
  134. VOID
  135. );
  136. };