home *** CD-ROM | disk | FTP | other *** search
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- #define new DEBUG_NEW
-
- /////////////////////////////////////////////////////////////////////////////
- // CSemaphore
-
- CSemaphore::CSemaphore(LONG lInitialCount, LONG lMaxCount,
- LPCTSTR pstrName, LPSECURITY_ATTRIBUTES lpsaAttributes)
- : CSyncObject(pstrName)
- {
- ASSERT(lMaxCount > 0);
- ASSERT(lInitialCount <= lMaxCount);
-
- m_hObject = ::CreateSemaphore(lpsaAttributes, lInitialCount, lMaxCount,
- pstrName);
- if (m_hObject == NULL)
- AfxThrowResourceException();
- }
-
- CSemaphore::~CSemaphore()
- {
- }
-
- BOOL CSemaphore::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
- {
- return ::ReleaseSemaphore(m_hObject, lCount, lpPrevCount);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CMutex
-
- CMutex::CMutex(BOOL bInitiallyOwn, LPCTSTR pstrName,
- LPSECURITY_ATTRIBUTES lpsaAttribute /* = NULL */)
- : CSyncObject(pstrName)
- {
- m_hObject = ::CreateMutex(lpsaAttribute, bInitiallyOwn, pstrName);
- if (m_hObject == NULL)
- AfxThrowResourceException();
- }
-
- CMutex::~CMutex()
- {
- }
-
- BOOL CMutex::Unlock()
- {
- return ::ReleaseMutex(m_hObject);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CEvent
-
- CEvent::CEvent(BOOL bInitiallyOwn, BOOL bManualReset, LPCTSTR pstrName,
- LPSECURITY_ATTRIBUTES lpsaAttribute)
- : CSyncObject(pstrName)
- {
- m_hObject = ::CreateEvent(lpsaAttribute, bManualReset,
- bInitiallyOwn, pstrName);
- if (m_hObject == NULL)
- AfxThrowResourceException();
- }
-
- CEvent::~CEvent()
- {
- }
-
- BOOL CEvent::Unlock()
- {
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CSingleLock
-
- CSingleLock::CSingleLock(CSyncObject* pObject, BOOL bInitialLock)
- {
- ASSERT(pObject != NULL);
- ASSERT(pObject->IsKindOf(RUNTIME_CLASS(CSyncObject)));
-
- m_pObject = pObject;
- m_hObject = pObject->m_hObject;
- m_bAcquired = FALSE;
-
- if (bInitialLock)
- Lock();
- }
-
- BOOL CSingleLock::Lock(DWORD dwTimeOut /* = INFINITE */)
- {
- ASSERT(m_pObject != NULL || m_hObject != NULL);
- ASSERT(!m_bAcquired);
-
- m_bAcquired = m_pObject->Lock(dwTimeOut);
- return m_bAcquired;
- }
-
- BOOL CSingleLock::Unlock()
- {
- ASSERT(m_pObject != NULL);
- if (m_bAcquired)
- m_bAcquired = !m_pObject->Unlock();
-
- // successfully unlocking means it isn't acquired
- return !m_bAcquired;
- }
-
- BOOL CSingleLock::Unlock(LONG lCount, LPLONG lpPrevCount /* = NULL */)
- {
- ASSERT(m_pObject != NULL);
- if (m_bAcquired)
- m_bAcquired = !m_pObject->Unlock(lCount, lpPrevCount);
-
- // successfully unlocking means it isn't acquired
- return !m_bAcquired;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // CMultiLock
-
- CMultiLock::CMultiLock(CSyncObject* pObjects[], DWORD dwCount,
- BOOL bInitialLock)
- {
- ASSERT(dwCount > 0 && dwCount <= MAXIMUM_WAIT_OBJECTS);
- ASSERT(pObjects != NULL);
-
- m_ppObjectArray = pObjects;
- m_dwCount = dwCount;
-
- // as an optimization, skip allocating array if
- // we can use a small, preallocated bunch of handles
-
- if (m_dwCount > _countof(m_hPreallocated))
- {
- m_pHandleArray = new HANDLE[m_dwCount];
- m_bLockedArray = new BOOL[m_dwCount];
- }
- else
- {
- m_pHandleArray = m_hPreallocated;
- m_bLockedArray = m_bPreallocated;
- }
-
- // get list of handles from array of objects passed
- for (DWORD i = 0; i <m_dwCount; i++)
- {
- ASSERT_VALID(pObjects[i]);
- ASSERT(pObjects[i]->IsKindOf(RUNTIME_CLASS(CSyncObject)));
-
- // can't wait for critical sections
-
- ASSERT(!pObjects[i]->IsKindOf(RUNTIME_CLASS(CCriticalSection)));
-
- m_pHandleArray[i] = pObjects[i]->m_hObject;
- m_bLockedArray[i] = FALSE;
- }
-
- if (bInitialLock)
- Lock();
- }
-
- CMultiLock::~CMultiLock()
- {
- Unlock();
- if (m_pHandleArray != m_hPreallocated)
- {
- delete[] m_bLockedArray;
- delete[] m_pHandleArray;
- }
- }
-
- DWORD CMultiLock::Lock(DWORD dwTimeOut /* = INFINITE */,
- BOOL bWaitForAll /* = TRUE */, DWORD dwWakeMask /* = 0 */)
- {
- DWORD dwResult;
- if (dwWakeMask == 0)
- dwResult = ::WaitForMultipleObjects(m_dwCount,
- m_pHandleArray, bWaitForAll, dwTimeOut);
- else
- dwResult = ::MsgWaitForMultipleObjects(m_dwCount,
- m_pHandleArray, bWaitForAll, dwTimeOut, dwWakeMask);
-
- if (dwResult >= WAIT_OBJECT_0 && dwResult < (WAIT_OBJECT_0 + m_dwCount))
- {
- if (bWaitForAll)
- {
- for (DWORD i = 0; i < m_dwCount; i++)
- m_bLockedArray[i] = TRUE;
- }
- else
- {
- ASSERT((dwResult - WAIT_OBJECT_0) >= 0);
- m_bLockedArray[dwResult - WAIT_OBJECT_0] = TRUE;
- }
- }
- return dwResult;
- }
-
- BOOL CMultiLock::Unlock()
- {
- for (DWORD i=0; i < m_dwCount; i++)
- {
- if (m_bLockedArray[i])
- m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock();
- }
- return TRUE;
- }
-
- BOOL CMultiLock::Unlock(LONG lCount, LPLONG lpPrevCount /* =NULL */)
- {
- BOOL bGotOne = FALSE;
- for (DWORD i=0; i < m_dwCount; i++)
- {
- if (m_bLockedArray[i])
- {
- CSemaphore* pSemaphore = STATIC_DOWNCAST(CSemaphore, m_ppObjectArray[i]);
- if (pSemaphore != NULL)
- {
- bGotOne = TRUE;
- m_bLockedArray[i] = !m_ppObjectArray[i]->Unlock(lCount, lpPrevCount);
- }
- }
- }
-
- return bGotOne;
- }
-
- #ifdef AFX_INIT_SEG
- #pragma code_seg(AFX_INIT_SEG)
- #endif
-
- IMPLEMENT_DYNAMIC(CEvent, CSyncObject)
- IMPLEMENT_DYNAMIC(CSemaphore, CSyncObject)
- IMPLEMENT_DYNAMIC(CMutex, CSyncObject)
-
- /////////////////////////////////////////////////////////////////////////////
-