mtex.cpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  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 "stdafx.h"
  11. #ifdef _DEBUG
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. #define new DEBUG_NEW
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CSemaphore
  18. CSemaphore::CSemaphore(LONG lInitialCount, LONG lMaxCount,
  19. LPCTSTR pstrName, LPSECURITY_ATTRIBUTES lpsaAttributes)
  20. : CSyncObject(pstrName)
  21. {
  22. ASSERT(lMaxCount > 0);
  23. ASSERT(lInitialCount <= lMaxCount);
  24. m_hObject = ::CreateSemaphore(lpsaAttributes, lInitialCount, lMaxCount,
  25. pstrName);
  26. if (m_hObject == NULL)
  27. AfxThrowResourceException();
  28. }
  29. CSemaphore::~CSemaphore()
  30. {
  31. }
  32. BOOL CSemaphore::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
  33. {
  34. return ::ReleaseSemaphore(m_hObject, lCount, lpPrevCount);
  35. }
  36. /////////////////////////////////////////////////////////////////////////////
  37. // CMutex
  38. CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrName,
  39. LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */)
  40. : CSyncObject(pstrName)
  41. {
  42. m_hObject = ::CreateMutex(lpsaAttribute, bInitiallyOwn, pstrName);
  43. if (m_hObject == NULL)
  44. AfxThrowResourceException();
  45. }
  46. CMutex::~CMutex()
  47. {
  48. }
  49. BOOL CMutex::Unlock()
  50. {
  51. return ::ReleaseMutex(m_hObject);
  52. }
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CEvent
  55. CEvent::CEvent(BOOL bInitiallyOwn, BOOL bManualReset, LPCTSTR pstrName,
  56. LPSECURITY_ATTRIBUTES lpsaAttribute)
  57. : CSyncObject(pstrName)
  58. {
  59. m_hObject = ::CreateEvent(lpsaAttribute, bManualReset,
  60. bInitiallyOwn, pstrName);
  61. if (m_hObject == NULL)
  62. AfxThrowResourceException();
  63. }
  64. CEvent::~CEvent()
  65. {
  66. }
  67. BOOL CEvent::Unlock()
  68. {
  69. return TRUE;
  70. }
  71. /////////////////////////////////////////////////////////////////////////////
  72. // CSingleLock
  73. CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock)
  74. {
  75. ASSERT(pObject != NULL);
  76. ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CSyncObject)));
  77. m_pObject = pObject;
  78. m_hObject = pObject->m_hObject;
  79. m_bAcquired = FALSE;
  80. if (bInitialLock)
  81. Lock();
  82. }
  83. BOOL CSingleLock::Lock(DWORD dwTimeOut /* = INFINITE */)
  84. {
  85. ASSERT(m_pObject != NULL || m_hObject != NULL);
  86. ASSERT(!m_bAcquired);
  87. m_bAcquired = m_pObject->Lock(dwTimeOut);
  88. return m_bAcquired;
  89. }
  90. BOOL CSingleLock::Unlock()
  91. {
  92. ASSERT(m_pObject != NULL);
  93. if (m_bAcquired)
  94. m_bAcquired = !m_pObject->Unlock();
  95. // successfully unlocking means it isn't acquired
  96. return !m_bAcquired;
  97. }
  98. BOOL CSingleLock::Unlock(LONG lCount, LPLONG lpPrevCount /* = NULL */)
  99. {
  100. ASSERT(m_pObject != NULL);
  101. if (m_bAcquired)
  102. m_bAcquired = !m_pObject->Unlock(lCount, lpPrevCount);
  103. // successfully unlocking means it isn't acquired
  104. return !m_bAcquired;
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CMultiLock
  108. CMultiLock::CMultiLock(CSyncObject* pObjects[], DWORD dwCount,
  109. BOOL bInitialLock)
  110. {
  111. ASSERT(dwCount > 0 && dwCount <= MAXIMUM_WAIT_OBJECTS);
  112. ASSERT(pObjects != NULL);
  113. m_ppObjectArray = pObjects;
  114. m_dwCount = dwCount;
  115. // as an optimization, skip allocating array if
  116. // we can use a small, preallocated bunch of handles
  117. if (m_dwCount > _countof(m_hPreallocated))
  118. {
  119. m_pHandleArray = new HANDLE[m_dwCount];
  120. m_bLockedArray = new BOOL[m_dwCount];
  121. }
  122. else
  123. {
  124. m_pHandleArray = m_hPreallocated;
  125. m_bLockedArray = m_bPreallocated;
  126. }
  127. // get list of handles from array of objects passed
  128. for (DWORD i = 0; i <m_dwCount; i++)
  129. {
  130. ASSERT_VALID(pObjects[i]);
  131. ASSERT(pObjects[i]->IsKindOf(RUNTIME_CLASS(CSyncObject)));
  132. // can't wait for critical sections
  133. ASSERT(!pObjects[i]->IsKindOf(RUNTIME_CLASS(CCriticalSection)));
  134. m_pHandleArray[i] = pObjects[i]->m_hObject;
  135. m_bLockedArray[i] = FALSE;
  136. }
  137. if (bInitialLock)
  138. Lock();
  139. }
  140. CMultiLock::~CMultiLock()
  141. {
  142. Unlock();
  143. if (m_pHandleArray != m_hPreallocated)
  144. {
  145. delete[] m_bLockedArray;
  146. delete[] m_pHandleArray;
  147. }
  148. }
  149. DWORD CMultiLock::Lock(DWORD dwTimeOut /* = INFINITE */,
  150. BOOL bWaitForAll /* = TRUE */, DWORD dwWakeMask /* = 0 */)
  151. {
  152. DWORD dwResult;
  153. if (dwWakeMask == 0)
  154. dwResult = ::WaitForMultipleObjects(m_dwCount,
  155. m_pHandleArray, bWaitForAll, dwTimeOut);
  156. else
  157. dwResult = ::MsgWaitForMultipleObjects(m_dwCount,
  158. m_pHandleArray, bWaitForAll, dwTimeOut, dwWakeMask);
  159. if (dwResult >= WAIT_OBJECT_0 && dwResult < (WAIT_OBJECT_0 + m_dwCount))
  160. {
  161. if (bWaitForAll)
  162. {
  163. for (DWORD i = 0; i < m_dwCount; i++)
  164. m_bLockedArray[i] = TRUE;
  165. }
  166. else
  167. {
  168. ASSERT((dwResult - WAIT_OBJECT_0) >= 0);
  169. m_bLockedArray[dwResult - WAIT_OBJECT_0] = TRUE;
  170. }
  171. }
  172. return dwResult;
  173. }
  174. BOOL CMultiLock::Unlock()
  175. {
  176. for (DWORD i=0; i < m_dwCount; i++)
  177. {
  178. if (m_bLockedArray[i])
  179. m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock();
  180. }
  181. return TRUE;
  182. }
  183. BOOL CMultiLock::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
  184. {
  185. BOOL bGotOne = FALSE;
  186. for (DWORD i=0; i < m_dwCount; i++)
  187. {
  188. if (m_bLockedArray[i])
  189. {
  190. CSemaphore* pSemaphore = STATIC_DOWNCAST(CSemaphore, m_ppObjectArray[i]);
  191. if (pSemaphore != NULL)
  192. {
  193. bGotOne = TRUE;
  194. m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock(lCount, lpPrevCount);
  195. }
  196. }
  197. }
  198. return bGotOne;
  199. }
  200. #ifdef AFX_INIT_SEG
  201. #pragma code_seg(AFX_INIT_SEG)
  202. #endif
  203. IMPLEMENT_DYNAMIC(CEvent, CSyncObject)
  204. IMPLEMENT_DYNAMIC(CSemaphore, CSyncObject)
  205. IMPLEMENT_DYNAMIC(CMutex, CSyncObject)
  206. /////////////////////////////////////////////////////////////////////////////