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.

221 lines
4.0 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1995 - 1999
  3. Module Name:
  4. Locks.hxx
  5. Abstract:
  6. Several small class (CInterlockedInteger, CMutexLock and CSharedLock
  7. which are wrappers for Win32 APIs.
  8. CInterlockedInteger is a simple wrapper for win32 interlockedm integer APis.
  9. CMutexLock is a wrapper designed to automatically constructed around
  10. win32 critical sections. They never forget to release the lock.
  11. CSharedLocks are similar to NT resources, they allow shared (multiple readers)
  12. and exclusive (single writer) access to the resource. They are different
  13. in the following ways:
  14. CSharedLocks don't starve exclusive threads.
  15. Exclusive threads spin (Sleep(0)) while waiting for readers to finish.
  16. Exclusive threads will deadlock trying to gain shared access.
  17. Exclusive threads trying to recursively take the lock may deadlock.
  18. They always block if they can't get access.
  19. Author:
  20. Mario Goertzel [MarioGo]
  21. Revision History:
  22. MarioGo 03-14-95 Moved from misc.?xx
  23. --*/
  24. #ifndef __LOCKS_HXX
  25. #define __LOCKS_HXX
  26. class CInterlockedInteger
  27. {
  28. private:
  29. LONG i;
  30. public:
  31. CInterlockedInteger(LONG i = 0) : i(i) {}
  32. LONG operator++(int)
  33. {
  34. return(InterlockedIncrement(&i));
  35. }
  36. LONG operator--(int)
  37. {
  38. return(InterlockedDecrement(&i));
  39. }
  40. operator LONG()
  41. {
  42. return(i);
  43. }
  44. };
  45. class CMutexLock
  46. {
  47. private:
  48. CRITICAL_SECTION *pCurrentLock;
  49. int owned;
  50. public:
  51. CMutexLock(CRITICAL_SECTION *pLock) : owned(0), pCurrentLock(pLock) {
  52. Lock();
  53. }
  54. ~CMutexLock() {
  55. if (owned)
  56. Unlock();
  57. #if DBG
  58. pCurrentLock = 0;
  59. #endif
  60. }
  61. void Lock()
  62. {
  63. ASSERT(!owned);
  64. EnterCriticalSection(pCurrentLock);
  65. owned = 1;
  66. }
  67. void Unlock()
  68. {
  69. ASSERT(owned);
  70. LeaveCriticalSection(pCurrentLock);
  71. owned = 0;
  72. }
  73. };
  74. class CSharedLock
  75. {
  76. private:
  77. CRITICAL_SECTION lock;
  78. HANDLE hevent;
  79. CInterlockedInteger readers;
  80. LONG writers;
  81. DWORD exclusive_owner;
  82. public:
  83. CSharedLock();
  84. ~CSharedLock();
  85. void LockShared(void);
  86. void UnlockShared(void);
  87. void LockExclusive(void);
  88. void UnlockExclusive(void);
  89. void Unlock(void);
  90. void ConvertToExclusive(void);
  91. BOOL HeldExclusive()
  92. {
  93. return(exclusive_owner == GetCurrentThreadId());
  94. }
  95. BOOL NotHeldExclusiveByAnyone()
  96. {
  97. return(exclusive_owner == 0);
  98. }
  99. };
  100. class CAutoExclusiveLock
  101. {
  102. public:
  103. CAutoExclusiveLock( CSharedLock & sl ) : _sl( sl )
  104. {
  105. if (!_sl.HeldExclusive())
  106. {
  107. sl.LockExclusive();
  108. held = 1;
  109. }
  110. else
  111. {
  112. held = 0;
  113. }
  114. }
  115. ~CAutoExclusiveLock()
  116. {
  117. while (held--)
  118. {
  119. _sl.UnlockExclusive();
  120. }
  121. }
  122. void LockExclusive(void)
  123. {
  124. _sl.LockExclusive();
  125. ++held;
  126. }
  127. void UnlockExclusive(void)
  128. {
  129. _sl.UnlockExclusive();
  130. --held;
  131. }
  132. protected:
  133. CSharedLock & _sl;
  134. BOOL held;
  135. };
  136. class CAutoSharedLock
  137. {
  138. public:
  139. CAutoSharedLock( CSharedLock & sl ) : _sl( sl )
  140. {
  141. sl.LockShared();
  142. held = 1;
  143. }
  144. ~CAutoSharedLock()
  145. {
  146. while (held--)
  147. {
  148. _sl.UnlockShared();
  149. }
  150. }
  151. void LockShared(void)
  152. {
  153. _sl.LockShared();
  154. ++held;
  155. }
  156. void UnlockShared(void)
  157. {
  158. _sl.UnlockShared();
  159. --held;
  160. }
  161. protected:
  162. CSharedLock & _sl;
  163. BOOL held;
  164. };
  165. #endif // __LOCKS_HXX