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.

196 lines
4.6 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft OLE
  4. // Copyright (C) Microsoft Corporation, 1994 - 1995.
  5. //
  6. // File: semshare.hxx
  7. //
  8. // Contents: Semaphore class for sharing a resource between read and
  9. // write threads.
  10. //
  11. // Classes: CSemShare
  12. //
  13. // Functions:
  14. //
  15. // History: 11-20-94 kennethm Created
  16. //
  17. //--------------------------------------------------------------------------
  18. //+-------------------------------------------------------------------------
  19. //
  20. // Class: CSemShare ()
  21. //
  22. // Purpose:
  23. //
  24. // Interface: CShareSem -- Contructor
  25. // ~CShareSem -- Destructor
  26. // AquireRead -- Gives the caller read access to the resource
  27. // AquireWrite -- Gives the caller write access to the resource
  28. // ReleaseRead -- Releases read access to the resource
  29. // ReleaseWrite -- Releases write access to the resource
  30. //
  31. // History: 11-20-94 kennethm Created
  32. //
  33. // Notes:
  34. //
  35. //--------------------------------------------------------------------------
  36. class CSemShare
  37. {
  38. public:
  39. inline CSemShare();
  40. inline ~CSemShare();
  41. inline HRESULT AcquireRead();
  42. inline HRESULT AcquireWrite();
  43. inline HRESULT ReleaseRead();
  44. inline HRESULT ReleaseWrite();
  45. private:
  46. HANDLE m_hEventDataReady;
  47. HANDLE m_hSemReaders;
  48. HANDLE m_hMutexWriters;
  49. LONG m_lReaderCount;
  50. };
  51. inline CSemShare::CSemShare()
  52. {
  53. m_hEventDataReady = CreateEvent(NULL, TRUE, TRUE, NULL);
  54. m_hSemReaders = CreateSemaphore(NULL, 1, 1, NULL);
  55. m_hMutexWriters = CreateMutex(NULL, FALSE, NULL);
  56. m_lReaderCount = -1;
  57. }
  58. inline CSemShare::~CSemShare()
  59. {
  60. CloseHandle(m_hEventDataReady);
  61. CloseHandle(m_hSemReaders);
  62. CloseHandle(m_hMutexWriters);
  63. }
  64. inline HRESULT CSemShare::AcquireRead()
  65. {
  66. WaitForSingleObject(m_hEventDataReady, INFINITE);
  67. if (InterlockedIncrement(&m_lReaderCount) == 0)
  68. {
  69. WaitForSingleObject(m_hSemReaders, INFINITE);
  70. }
  71. return S_OK;
  72. }
  73. inline HRESULT CSemShare::AcquireWrite()
  74. {
  75. //
  76. // Wait for any other writers to finish
  77. //
  78. WaitForSingleObject(m_hMutexWriters, INFINITE);
  79. //
  80. // Block any new readers from starting
  81. //
  82. ResetEvent(m_hEventDataReady);
  83. //
  84. // Wait for any readers still reading the resources
  85. //
  86. WaitForSingleObject(m_hSemReaders, INFINITE);
  87. return S_OK;
  88. }
  89. inline HRESULT CSemShare::ReleaseRead()
  90. {
  91. //
  92. // Decrement the number of readers. If we are the last
  93. // reader then release the reader semaphore.
  94. //
  95. if (InterlockedDecrement(&m_lReaderCount) < 0)
  96. {
  97. ReleaseSemaphore(m_hSemReaders, 1, NULL);
  98. }
  99. return S_OK;
  100. }
  101. inline HRESULT CSemShare::ReleaseWrite()
  102. {
  103. //
  104. // Let readers know the resource is available again
  105. //
  106. SetEvent(m_hEventDataReady);
  107. //
  108. // Let readers read the resource
  109. //
  110. ReleaseSemaphore(m_hSemReaders, 1, NULL);
  111. //
  112. // Let another writer reserve access to the resource
  113. //
  114. ReleaseMutex(m_hMutexWriters);
  115. return S_OK;
  116. }
  117. //+---------------------------------------------------------------------------
  118. //
  119. // Class: CReadLock
  120. //
  121. // Purpose: Lock using a Resource monitor
  122. //
  123. // History: 24-Feb-93 WadeR Created.
  124. //
  125. // Notes: Simple lock object to be created on the stack.
  126. // The constructor acquires the resource, the destructor
  127. // (called when lock is going out of scope) releases it.
  128. //
  129. //----------------------------------------------------------------------------
  130. class CReadLock
  131. {
  132. public:
  133. CReadLock ( CSemShare& r ) : _r(r)
  134. { _r.AcquireRead(); };
  135. ~CReadLock ()
  136. { _r.ReleaseRead(); };
  137. private:
  138. CSemShare& _r;
  139. };
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Class: CWriteLock
  143. //
  144. // Purpose: Lock using a Resource monitor
  145. //
  146. // History: 24-Feb-93 WadeR Created.
  147. //
  148. // Notes: Simple lock object to be created on the stack.
  149. // The constructor acquires the resource, the destructor
  150. // (called when lock is going out of scope) releases it.
  151. //
  152. //----------------------------------------------------------------------------
  153. class CWriteLock
  154. {
  155. public:
  156. CWriteLock ( CSemShare& r ) : _r(r)
  157. { _r.AcquireWrite(); };
  158. ~CWriteLock ()
  159. { _r.ReleaseWrite(); };
  160. private:
  161. CSemShare& _r;
  162. };