home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / vc98 / mfc / src / mtex.cpp < prev    next >
C/C++ Source or Header  |  1998-06-16  |  6KB  |  252 lines

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