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 >
Wrap
C/C++ Source or Header
|
1998-06-16
|
6KB
|
252 lines
// 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)
/////////////////////////////////////////////////////////////////////////////