Source code of Windows XP (NT5)
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.

188 lines
4.8 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. LOCK.H
  5. Abstract:
  6. Generic class for obtaining read and write locks to some resource.
  7. See lock.h for all documentation.
  8. Classes defined:
  9. CLock
  10. History:
  11. a-levn 5-Sept-96 Created.
  12. 3/10/97 a-levn Fully documented
  13. --*/
  14. #ifndef __GATEWAY__LOCK__H_
  15. #define __GATEWAY__LOCK__H_
  16. #include <lockst.h>
  17. //*****************************************************************************
  18. //
  19. // class CLock
  20. //
  21. // Generic class for obtaining read and write locks to some resource.
  22. // Simultaneous reads are allowed, but no concurrent writes or concurrent
  23. // read and write accesses are.
  24. //
  25. // NOTE: this class is for in-process sinchronization only!
  26. //
  27. // Usage: create an instance of this class and share it among the accessing
  28. // threads. Threads must call member functions of the same instance to
  29. // obtain and release locks.
  30. //
  31. //*****************************************************************************
  32. //
  33. // ReadLock
  34. //
  35. // Use this function to request read access to the resource. Access will be
  36. // granted once no threads are writing on the resource. You must call
  37. // ReadUnlock once you are done reading.
  38. //
  39. // Parameters:
  40. //
  41. // DWORD dwTimeout The number of milliseconds to wait for access.
  42. // If access is still unavailable after this time,
  43. // an error is returned.
  44. // Returns:
  45. //
  46. // NoError On Success
  47. // TimedOut On timeout.
  48. // Failed On system error
  49. //
  50. //*****************************************************************************
  51. //
  52. // ReadUnlock
  53. //
  54. // Use this function to release a read lock on the resource. No check is
  55. // performed to assertain that this thread holds a lock. Unmatched calls to
  56. // ReadUnlock may lead to lock integrity violations!
  57. //
  58. // Returns:
  59. //
  60. // NoError On success
  61. // Failed On system error or unmatched call.
  62. //
  63. //*****************************************************************************
  64. //
  65. // WriteLock
  66. //
  67. // Use this function to request write access to the resource. Access will be
  68. // granted once no threads are reading or writing on the resource. You must
  69. // call WriteUnlock once you are done writing.
  70. //
  71. // Parameters:
  72. //
  73. // DWORD dwTimeout The number of milliseconds to wait for access.
  74. // If access is still unavailable after this time,
  75. // an error is returned.
  76. // Returns:
  77. //
  78. // NoError On Success
  79. // TimedOut On timeout.
  80. // Failed On system error
  81. //
  82. //*****************************************************************************
  83. //
  84. // WriteUnlock
  85. //
  86. // Use this function to release a write lock on the resource. No check is
  87. // performed to assertain that this thread holds a lock. Unmatched calls to
  88. // WriteUnlock may lead to lock integrity violations!
  89. //
  90. // Returns:
  91. //
  92. // NoError On success
  93. // Failed On system error or unmatched call.
  94. //
  95. //*****************************************************************************
  96. //
  97. // DowngradeLock
  98. //
  99. // Use this function to "convert" a Write lock into a Read lock. That is, if
  100. // you are currently holding a write lock and call DowngradeLock, you will
  101. // be holding a read lock with the guarantee that no one wrote anything between
  102. // the unlock and the lock
  103. //
  104. // Returns:
  105. //
  106. // NoError On Success
  107. // Failed On system error or unmatched call
  108. //
  109. //******************************************************************************
  110. class CLock
  111. {
  112. public:
  113. enum { NoError = 0, TimedOut, Failed };
  114. int ReadLock(DWORD dwTimeout = INFINITE);
  115. int ReadUnlock();
  116. int WriteLock(DWORD dwTimeout = INFINITE);
  117. int WriteUnlock();
  118. int DowngradeLock();
  119. CLock();
  120. ~CLock();
  121. protected:
  122. int WaitFor(HANDLE hEvent, DWORD dwTimeout);
  123. protected:
  124. int m_nWriting;
  125. int m_nReading;
  126. int m_nWaitingToWrite;
  127. int m_nWaitingToRead;
  128. CriticalSection m_csEntering;
  129. CriticalSection m_csAll;
  130. HANDLE m_hCanWrite;
  131. HANDLE m_hCanRead;
  132. DWORD m_WriterId;
  133. //CFlexArray m_adwReaders;
  134. enum { MaxRegistredReaders = 16,
  135. MaxTraceSize = 7};
  136. DWORD m_dwArrayIndex;
  137. struct {
  138. DWORD ThreadId;
  139. //PVOID Trace[MaxTraceSize];
  140. } m_adwReaders[MaxRegistredReaders];
  141. };
  142. class CAutoReadLock
  143. {
  144. public:
  145. CAutoReadLock(CLock *lock) : m_lock(lock), m_bLocked(FALSE) { }
  146. ~CAutoReadLock() { Unlock(); }
  147. void Unlock() {if ( m_bLocked) { m_lock->ReadUnlock(); m_bLocked = FALSE; } }
  148. bool Lock() {if (!m_bLocked) { return m_bLocked = (CLock::NoError == m_lock->ReadLock()) ; } else {return false;}; }
  149. private:
  150. CLock *m_lock;
  151. BOOL m_bLocked;
  152. };
  153. class CAutoWriteLock
  154. {
  155. public:
  156. CAutoWriteLock(CLock *lock) : m_lock(lock), m_bLocked(FALSE) { }
  157. ~CAutoWriteLock() { Unlock(); }
  158. void Unlock() {if ( m_bLocked) { m_lock->WriteUnlock(); m_bLocked = FALSE; } }
  159. bool Lock() {if (!m_bLocked) { return m_bLocked = (CLock::NoError == m_lock->WriteLock()); } else { return false; }; }
  160. private:
  161. CLock *m_lock;
  162. BOOL m_bLocked;
  163. };
  164. #endif