www.pudn.com > WinGOS.rar > SyncObject.cpp


#include "GOS.h" 
#include "SyncObject.h" 
 
#define EVENT_SETED 0x01L 
#define EVENT_AUTO 0x02L 
#define PTR_MASK ~0x03L 
#define HAS_PROXY 1L 
 
void CSyncObject::LockEx(CThread* pThread,LONG nTimeOut) 
{ 
	nTimeOut+=GetTickCount(); 
	pThread->m_pWaitObject=this; 
	pThread->m_nWakeTime=nTimeOut; 
} 
 
CCriticalSection::CCriticalSection() 
{ 
	m_nData=NULL; 
} 
 
BOOL CCriticalSection::Lock(LONG nTimeOut) 
{ 
	BOOL bResult; 
	PTHREAD pThread=GetCurrentThread(); 
 
	DisableSwitchThread(); 
	bResult=!m_nData; 
	if(bResult) 
		m_nData=DWORD(pThread); 
	EnableSwitchThread(); 
 
	if(!bResult && nTimeOut) 
	{ 
		LockEx(pThread,nTimeOut); 
		SwitchToThread(); 
		//µÈºò»½ÐÑ...ÒÑ»½ÐÑ 
		if(pThread->m_pWaitObject) 
			pThread->m_pWaitObject=NULL; 
		else 
			bResult=TRUE; 
	} 
	return bResult; 
} 
 
BOOL CCriticalSection::Unlock() 
{ 
	DWORD nOwner=m_nData; 
	if(nOwner) 
	{ 
		m_nData=NULL; 
		if(nOwner & HAS_PROXY) 
			SwitchToThread(); 
	} 
	return nOwner; 
} 
 
CThread* CCriticalSection::FindProxy(CThread* pWaiter,LONG nCurTime) 
{ 
	DWORD nOwner=m_nData; 
	if(nOwner) 
	{ 
		if(nOwner & HAS_PROXY) 
			nOwner &= PTR_MASK; 
		else 
			m_nData=nOwner | HAS_PROXY; 
		pWaiter=PTHREAD(nOwner); 
	} 
	else 
	{ 
		m_nData=DWORD(pWaiter); 
		pWaiter->m_pWaitObject=NULL; 
	} 
	return pWaiter; 
} 
 
CMutex::CMutex(BOOL bInitialOwn) 
{ 
	m_nData=bInitialOwn?DWORD(GetCurrentThread()):NULL; 
} 
 
CMutex::CMutex(CThread* pInitialOwn) 
{ 
	m_nData=DWORD(pInitialOwn); 
} 
 
CThread* CMutex::FindProxy(CThread* pWaiter,LONG nCurTime) 
{ 
	DWORD nOwner=m_nData; 
	if(nOwner) 
	{ 
		if(nOwner & HAS_PROXY) 
			nOwner &= PTR_MASK; 
		else 
			m_nData=nOwner | HAS_PROXY; 
		pWaiter=PTHREAD(nOwner); 
		if(LONG(pWaiter->m_nWakeTime-nCurTime)>0) 
			pWaiter=NULL; 
	} 
	else 
	{ 
		m_nData=DWORD(pWaiter); 
		pWaiter->m_pWaitObject=NULL; 
	} 
	return pWaiter; 
} 
 
CSemaphore::CSemaphore(LONG nInitialCount) 
{ 
	m_nCount=nInitialCount; 
	m_nIntCount=0; 
	m_nData=DWORD(GetCurrentThread()); 
} 
 
BOOL CSemaphore::Lock(LONG nTimeOut) 
{ 
	BOOL bResult; 
	PTHREAD pThread=GetCurrentThread(); 
 
	DisableSwitchThread(); 
	bResult=LONG(m_nCount+m_nIntCount)>0; 
	if(bResult) 
	{ 
		m_nCount--; 
		m_nData=DWORD(pThread); 
	} 
	EnableSwitchThread(); 
 
	if(!bResult && nTimeOut) 
	{ 
		LockEx(pThread,nTimeOut); 
		SwitchToThread(); 
		//µÈºò»½ÐÑ...ÒÑ»½ÐÑ 
		if(pThread->m_pWaitObject) 
			pThread->m_pWaitObject=NULL; 
		else 
			bResult=TRUE; 
	} 
	return bResult; 
} 
 
BOOL CSemaphore::Unlock() 
{ 
	if(IsInterruptMode()) 
	{ 
		m_nIntCount++; 
		m_nData=NULL; 
	} 
	else 
	{ 
		DisableSwitchThread(); 
		m_nCount++; 
		m_nData=NULL; 
		EnableSwitchThread(); 
	} 
	SwitchToThread(); 
	return TRUE; 
} 
 
CThread* CSemaphore::FindProxy(CThread* pWaiter,LONG nCurTime) 
{ 
	if(LONG(m_nCount+m_nIntCount)>0) 
	{ 
		m_nCount--; 
		m_nData=DWORD(pWaiter); 
		pWaiter->m_pWaitObject=NULL; 
	} 
	else 
	{ 
		pWaiter=PTHREAD(m_nData); 
		if(LONG(pWaiter->m_nWakeTime-nCurTime)>0)pWaiter=NULL; 
	} 
	return pWaiter; 
} 
 
CEvent::CEvent(BOOL bInitialOwn,BOOL bManualReset) 
{ 
	DWORD nTag=0; 
	if(bInitialOwn) 
		nTag |= EVENT_SETED; 
	if(!bManualReset) 
		nTag |= EVENT_AUTO; 
	m_nData=nTag; 
} 
 
BOOL CEvent::Lock(LONG nTimeOut) 
{ 
	BOOL bResult; 
	DWORD nTag=m_nData; 
	PTHREAD pThread=GetCurrentThread(); 
 
	if(nTag & EVENT_AUTO) 
	{ 
		DisableSwitchThread(); 
		bResult=m_nData & EVENT_SETED; 
		if(bResult)m_nData=EVENT_AUTO | DWORD(pThread); 
		EnableSwitchThread(); 
	} 
	else 
		bResult=(nTag & EVENT_SETED); 
	 
	if(!bResult && nTimeOut) 
	{ 
		LockEx(pThread,nTimeOut); 
		SwitchToThread(); 
		//µÈºò»½ÐÑ...ÒÑ»½ÐÑ 
		if(pThread->m_pWaitObject) 
			pThread->m_pWaitObject=NULL; 
		else 
			bResult=TRUE; 
	} 
	return bResult; 
} 
 
BOOL CEvent::Unlock() 
{ 
	return SetEvent(); 
} 
 
CThread* CEvent::FindProxy(CThread* pWaiter,LONG nCurTime) 
{ 
	DWORD nTag=m_nData; 
	if(nTag & EVENT_AUTO) 
	{ 
		if(nTag & EVENT_SETED) 
		{ 
			m_nData=EVENT_AUTO | DWORD(pWaiter); 
			pWaiter->m_pWaitObject=NULL; 
		} 
		else 
		{ 
			pWaiter = PTHREAD(nTag & PTR_MASK); 
			if(pWaiter && LONG(pWaiter->m_nWakeTime-nCurTime)>0) 
				pWaiter=NULL; 
		} 
	} 
	else if(nTag & EVENT_SETED) 
		pWaiter->m_pWaitObject=NULL; 
	else 
		pWaiter=NULL; 
	return pWaiter; 
} 
 
BOOL CEvent::ResetEvent() 
{ 
	*PDWORD(&m_nData) &= EVENT_AUTO; 
	return TRUE; 
} 
 
BOOL CEvent::SetEvent() 
{ 
	m_nData=(m_nData & EVENT_AUTO) | EVENT_SETED; 
	SwitchToThread(); 
	return TRUE; 
}