定义部分:
// CThEventObj
class CThEventObj
{
public:
CThEventObj(BOOL bManualReset);
~CThEventObj();
void Set();
void Reset();
__UINT32 Wait(__UINT32 dwMilliseconds);
private:
CThEventObj();
CThEventObj(const CThEventObj &);
CThEventObj & operator = (const CThEventObj &);
private:
#ifdef WIN32
HANDLE m_hEvent;
#else
pthread_mutex_t m_mp;
pthread_cond_t m_cv;
volatile int m_flag; // 0 ûÓÐʼþ; 1 ÓÐʼþÁË
BOOL m_bManualReset; // TRUE ÊÖ¹¤RESET; FALSE ×Ô¶¯×ª»»×´Ì¬
#endif
};
/
实现部分:
CThEventObj::CThEventObj(BOOL bManualReset)
{
#ifdef WIN32
m_hEvent = ::CreateEvent(NULL,
bManualReset,
FALSE,
NULL
);
THROW_IF_NULL(m_hEvent);
#else // !WIN32
pthread_mutex_init(&m_mp, NULL);
pthread_cond_init(&m_cv, NULL);
m_flag = 0;
m_bManualReset = bManualReset;
#endif // !WIN32
}
CThEventObj::~CThEventObj()
{
#ifdef WIN32
::CloseHandle(m_hEvent); //lint !e534 ignored the return value
m_hEvent = NULL;
#else // !WIN32
pthread_mutex_destroy(&m_mp);
pthread_cond_destroy(&m_cv);
#endif // !WIN32
}
void CThEventObj::Set()
{
#ifdef WIN32
BOOL bRet = ::SetEvent(m_hEvent);
COM_ASSERT(bRet);
#else // !WIN32
pthread_mutex_lock(&m_mp);
m_flag = 1;
pthread_cond_signal(&m_cv);
pthread_mutex_unlock(&m_mp);
#endif // !WIN32
}
void CThEventObj::Reset()
{
#ifdef WIN32
BOOL bRet = ::ResetEvent(m_hEvent);
COM_ASSERT(bRet);
#else // !WIN32
pthread_mutex_lock(&m_mp);
m_flag = 0;
pthread_mutex_unlock(&m_mp);
#endif // !WIN32
}
__UINT32 CThEventObj::Wait(__UINT32 dwMilliseconds)
{
#ifdef WIN32
return (__UINT32)::WaitForSingleObject(m_hEvent, dwMilliseconds);
#else // !WIN32
if (INFINITE == dwMilliseconds)
{
pthread_mutex_lock(&m_mp);
while (0 == m_flag)
{
// the pthread_cond_wait call will release the m_mp and then wait m_cv be signed
// after m_cb be signed, the pthread_cond_wait will lock m_mp again
pthread_cond_wait(&m_cv, &m_mp);
}
if (!m_bManualReset)
{
m_flag = 0;
}
pthread_mutex_unlock(&m_mp);
return WAIT_OBJECT_0;
}
__UINT32 dwWaitResult = WAIT_TIMEOUT;
if (dwMilliseconds == IGNORE)
{
if (pthread_mutex_trylock(&m_mp) == EBUSY)
{
return WAIT_TIMEOUT;
}
if (1 == m_flag)
{
dwWaitResult = WAIT_OBJECT_0;
if (!m_bManualReset)
{
m_flag = 0;
}
}
pthread_mutex_unlock(&m_mp);
return dwWaitResult;
}
pthread_mutex_lock(&m_mp);
struct timespec abst;
struct timeval timeTemp;
gettimeofday(&timeTemp, NULL);
abst.tv_sec = timeTemp.tv_sec + dwMilliseconds / 1000;
abst.tv_nsec = (dwMilliseconds % 1000) * 1000 * 1000
+ timeTemp.tv_usec * 1000
;
if (abst.tv_nsec >= 1000000000)
{
abst.tv_sec++;
abst.tv_nsec -= 1000000000;
}
while (0 == m_flag)
{
dwWaitResult = (__UINT32)pthread_cond_timedwait(&m_cv, &m_mp, &abst);
if (0 == dwWaitResult)
{
if (0 == m_flag)
{
// Reset will cause m_flag = 0
continue;
}
if (!m_bManualReset)
{
m_flag = 0;
}
pthread_mutex_unlock(&m_mp);
return WAIT_OBJECT_0;
}
if (ETIMEDOUT == dwWaitResult)
{
pthread_mutex_unlock(&m_mp);
return WAIT_TIMEOUT;
}
}
if (!m_bManualReset) //×Ô¶¯RESET
{
m_flag = 0;
}
pthread_mutex_unlock(&m_mp);
return WAIT_OBJECT_0;
#endif // !WIN32
}