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.

183 lines
4.6 KiB

  1. #ifndef _CEXRWLCK_H
  2. #define _CEXRWLCK_H
  3. #include <limits.h>
  4. #ifndef WIN16
  5. //
  6. // This class contains the meat - does actual locking etc...
  7. //
  8. class CExShareLock {
  9. private :
  10. long cReadLock ; // Number of Readers who have passed through the lock OR
  11. // the number of readers waiting for the lock (will be negative).
  12. // A value of 0 means nobody in the lock
  13. long cOutRdrs ; // The number of readers remainin in the lock if
  14. // there is a writer waiting. This can become temporarily negative
  15. CRITICAL_SECTION critWriters ; // Critical section to allow only one writer into the lock at a time
  16. HANDLE hWaitingWriters ; // Semaphore for waiting writers to block on (Only 1 ever, others will
  17. // be queued on critWriters)
  18. HANDLE hWaitingReaders ; // Semaphore for waiting readers to block on
  19. public :
  20. CExShareLock( ) ;
  21. ~CExShareLock( ) ;
  22. void ShareLock( ) ;
  23. void ShareUnlock( ) ;
  24. void ExclusiveLock( ) ;
  25. void ExclusiveUnlock( ) ;
  26. BOOL SharedToExclusive( ) ; // returns TRUE if successful
  27. } ;
  28. //
  29. // This class implements a wrapper class around CExShareLock class so that
  30. // it alows the nested hold on Exclusive lock if a thread
  31. // has an exclusive lock and calls for holding exclusive lock or Share lock
  32. // again
  33. //
  34. class CExShareLockWithNestAllowed
  35. {
  36. private :
  37. CExShareLock m_lock; // class around which the wrapper is formed
  38. DWORD m_dwThreadID; // The thread id of the thred currently holding
  39. // the exclusive lock
  40. DWORD m_dwNestCount; // The count of number of nested calls to lock by the thread holding the
  41. // exclusive lock less 1
  42. public :
  43. CExShareLockWithNestAllowed( ) : m_dwThreadID(0xffffffff), m_dwNestCount(0)
  44. {
  45. // nothing
  46. };
  47. ~CExShareLockWithNestAllowed( )
  48. {
  49. Assert( (m_dwThreadID == 0xffffffff ) && ( m_dwNestCount == 0 ) );
  50. }
  51. void ShareLock( )
  52. {
  53. if(! nest() )
  54. {
  55. m_lock.ShareLock();
  56. }
  57. }
  58. void ShareUnlock( )
  59. {
  60. if (! unnest() )
  61. {
  62. m_lock.ShareUnlock();
  63. }
  64. }
  65. void ExclusiveLock( )
  66. {
  67. if(! nest() )
  68. {
  69. m_lock.ExclusiveLock();
  70. Assert( m_dwNestCount == 0 );
  71. Assert( m_dwThreadID == 0xffffffff );
  72. m_dwThreadID = GetCurrentThreadId();
  73. }
  74. }
  75. void ExclusiveUnlock( )
  76. {
  77. if (! unnest() )
  78. {
  79. m_dwThreadID = 0xffffffff;
  80. m_lock.ExclusiveUnlock();
  81. }
  82. }
  83. protected :
  84. BOOL nest()
  85. {
  86. if( m_dwThreadID != GetCurrentThreadId() )
  87. return ( FALSE );
  88. m_dwNestCount++;
  89. return( TRUE );
  90. }
  91. BOOL unnest()
  92. {
  93. if ( ! m_dwNestCount )
  94. return ( FALSE );
  95. Assert( m_dwThreadID == GetCurrentThreadId() );
  96. m_dwNestCount--;
  97. return( TRUE);
  98. }
  99. };
  100. #else
  101. class CExShareLock {
  102. public:
  103. CExShareLock() {
  104. InitializeCriticalSection(&m_cs);
  105. };
  106. ~CExShareLock() {
  107. DeleteCriticalSection(&m_cs);
  108. };
  109. void ShareLock(){
  110. EnterCriticalSection(&m_cs);
  111. };
  112. void ShareUnlock() {
  113. LeaveCriticalSection(&m_cs);
  114. };
  115. void ExclusiveLock(){
  116. EnterCriticalSection(&m_cs);
  117. };
  118. void ExclusiveUnlock() {
  119. LeaveCriticalSection(&m_cs);
  120. };
  121. BOOL SharedToExclusive() {
  122. return (TRUE);
  123. };
  124. private:
  125. CRITICAL_SECTION m_cs;
  126. };
  127. class CExShareLockWithNestAllowed {
  128. public:
  129. CExShareLockWithNestAllowed() {
  130. InitializeCriticalSection(&m_cs);
  131. };
  132. ~CExShareLockWithNestAllowed() {
  133. DeleteCriticalSection(&m_cs);
  134. };
  135. void ShareLock(){
  136. EnterCriticalSection(&m_cs);
  137. };
  138. void ShareUnlock() {
  139. LeaveCriticalSection(&m_cs);
  140. };
  141. void ExclusiveLock(){
  142. EnterCriticalSection(&m_cs);
  143. };
  144. void ExclusiveUnlock() {
  145. LeaveCriticalSection(&m_cs);
  146. };
  147. private:
  148. CRITICAL_SECTION m_cs;
  149. };
  150. #endif
  151. #endif