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.

218 lines
5.4 KiB

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (c) 1992-2001 Microsoft Corporation, All Rights Reserved
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "precomp.h"
  11. #include <provexpt.h>
  12. #include <plex.h>
  13. #include <provcoll.h>
  14. #include "provmt.h"
  15. #include "plex.h"
  16. bool CStaticCriticalSection::failureSet = false ;
  17. /////////////////////////////////////////////////////////////////////////////
  18. // CSemaphore
  19. CSemaphore::CSemaphore(LONG lInitialCount, LONG lMaxCount,
  20. LPCTSTR pstrName, LPSECURITY_ATTRIBUTES lpsaAttributes)
  21. : CSyncObject(pstrName)
  22. {
  23. m_hObject = ::CreateSemaphore(lpsaAttributes, lInitialCount, lMaxCount,
  24. pstrName);
  25. }
  26. CSemaphore::~CSemaphore()
  27. {
  28. }
  29. BOOL CSemaphore::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
  30. {
  31. return ::ReleaseSemaphore(m_hObject, lCount, lpPrevCount);
  32. }
  33. /////////////////////////////////////////////////////////////////////////////
  34. // CMutex
  35. CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrName,
  36. LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */)
  37. : CSyncObject(pstrName)
  38. {
  39. m_hObject = ::CreateMutex(lpsaAttribute, bInitiallyOwn, pstrName);
  40. }
  41. CMutex::~CMutex()
  42. {
  43. }
  44. BOOL CMutex::Unlock()
  45. {
  46. return ::ReleaseMutex(m_hObject);
  47. }
  48. /////////////////////////////////////////////////////////////////////////////
  49. // CEvent
  50. CEvent::CEvent(BOOL bInitiallyOwn, BOOL bManualReset, LPCTSTR pstrName,
  51. LPSECURITY_ATTRIBUTES lpsaAttribute)
  52. : CSyncObject(pstrName)
  53. {
  54. m_hObject = ::CreateEvent(lpsaAttribute, bManualReset,
  55. bInitiallyOwn, pstrName);
  56. }
  57. CEvent::~CEvent()
  58. {
  59. }
  60. BOOL CEvent::Unlock()
  61. {
  62. return TRUE;
  63. }
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CSingleLock
  66. CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock)
  67. {
  68. m_pObject = pObject;
  69. m_hObject = pObject->m_hObject;
  70. m_bAcquired = FALSE;
  71. if (bInitialLock)
  72. Lock();
  73. }
  74. BOOL CSingleLock::Lock(DWORD dwTimeOut /* = INFINITE */)
  75. {
  76. m_bAcquired = m_pObject->Lock(dwTimeOut);
  77. return m_bAcquired;
  78. }
  79. BOOL CSingleLock::Unlock()
  80. {
  81. if (m_bAcquired)
  82. m_bAcquired = !m_pObject->Unlock();
  83. // successfully unlocking means it isn't acquired
  84. return !m_bAcquired;
  85. }
  86. BOOL CSingleLock::Unlock(LONG lCount, LPLONG lpPrevCount /* = NULL */)
  87. {
  88. if (m_bAcquired)
  89. m_bAcquired = !m_pObject->Unlock(lCount, lpPrevCount);
  90. // successfully unlocking means it isn't acquired
  91. return !m_bAcquired;
  92. }
  93. /////////////////////////////////////////////////////////////////////////////
  94. // CMultiLock
  95. #define _countof(array) (sizeof(array)/sizeof(array[0]))
  96. CMultiLock::CMultiLock(CSyncObject* pObjects[], DWORD dwCount,
  97. BOOL bInitialLock) : m_pHandleArray ( NULL ) , m_bLockedArray ( NULL )
  98. {
  99. m_ppObjectArray = pObjects;
  100. m_dwCount = dwCount;
  101. // as an optimization, skip alloacating array if
  102. // we can use a small, predeallocated bunch of handles
  103. if (m_dwCount > _countof(m_hPreallocated))
  104. {
  105. m_pHandleArray = new HANDLE[m_dwCount];
  106. m_bLockedArray = new BOOL[m_dwCount];
  107. }
  108. else
  109. {
  110. m_pHandleArray = m_hPreallocated;
  111. m_bLockedArray = m_bPreallocated;
  112. }
  113. // get list of handles from array of objects passed
  114. for (DWORD i = 0; i <m_dwCount; i++)
  115. {
  116. m_pHandleArray[i] = pObjects[i]->m_hObject;
  117. m_bLockedArray[i] = FALSE;
  118. }
  119. if (bInitialLock)
  120. Lock();
  121. }
  122. CMultiLock::~CMultiLock()
  123. {
  124. Unlock();
  125. if (m_pHandleArray != m_hPreallocated)
  126. {
  127. delete[] m_bLockedArray;
  128. delete[] m_pHandleArray;
  129. }
  130. }
  131. DWORD CMultiLock::Lock(DWORD dwTimeOut /* = INFINITE */,
  132. BOOL bWaitForAll /* = TRUE */, DWORD dwWakeMask /* = 0 */)
  133. {
  134. DWORD dwResult;
  135. if (dwWakeMask == 0)
  136. dwResult = ::WaitForMultipleObjects(m_dwCount,
  137. m_pHandleArray, bWaitForAll, dwTimeOut);
  138. else
  139. dwResult = ::MsgWaitForMultipleObjects(m_dwCount,
  140. m_pHandleArray, bWaitForAll, dwTimeOut, dwWakeMask);
  141. if (dwResult < (WAIT_OBJECT_0 + m_dwCount))
  142. {
  143. if (bWaitForAll)
  144. {
  145. for (DWORD i = 0; i < m_dwCount; i++)
  146. m_bLockedArray[i] = TRUE;
  147. }
  148. else
  149. {
  150. m_bLockedArray[dwResult - WAIT_OBJECT_0] = TRUE;
  151. }
  152. }
  153. return dwResult;
  154. }
  155. BOOL CMultiLock::Unlock()
  156. {
  157. for (DWORD i=0; i < m_dwCount; i++)
  158. {
  159. if (m_bLockedArray[i])
  160. m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock();
  161. }
  162. return TRUE;
  163. }
  164. BOOL CMultiLock::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
  165. {
  166. BOOL bGotOne = FALSE;
  167. for (DWORD i=0; i < m_dwCount; i++)
  168. {
  169. if (m_bLockedArray[i])
  170. {
  171. CSemaphore* pSemaphore = ( CSemaphore *) m_ppObjectArray[i];
  172. if (pSemaphore != NULL)
  173. {
  174. bGotOne = TRUE;
  175. m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock(lCount, lpPrevCount);
  176. }
  177. }
  178. }
  179. return bGotOne;
  180. }
  181. /////////////////////////////////////////////////////////////////////////////