📄 oscond.cpp
字号:
/* File: OSCond.cpp Contains: Implementation of OSCond class */#include "OSCond.h"#include "OSMutex.h"#include "OSThread.h"#include "MyAssert.h"#if __PTHREADS_MUTEXES__#include <sys/time.h>#endif
OSCond::OSCond(){
#ifdef __Win32__ fWaitCount = 0; fCondition = ::CreateEvent(NULL, FALSE, FALSE, NULL); Assert(fCondition != NULL);#elif __PTHREADS_MUTEXES__ pthread_condattr_t cond_attr; pthread_condattr_init(&cond_attr); int ret = pthread_cond_init(&fCondition, &cond_attr); Assert(ret == 0);#else /* fCondition = mycondition_alloc(); Assert(fCondition != NULL); */#endif}OSCond::~OSCond(){#ifdef __Win32__ Bool theErr = ::CloseHandle(fCondition); Assert(theErr == TRUE);#elif __PTHREADS_MUTEXES__ pthread_cond_destroy(&fCondition);#else /* Assert(fCondition != NULL); mycondition_free(fCondition); */#endif}
/*
* 函数介绍:等待
* 输入参数:inMutex - 互斥量
* inTimeoutInMilSecs - 0 :阻塞,直到有信号
* 非0:阻塞,直到有信号或inTimeoutInMilSecs微秒后超时
* 使用前后应配合OSMutex::Lock,OSMutex::Unlock。
* 输出参数:无
* 返回值 :无
*/
//note: it's diffcult to confirm whether Wait() or Signal() scheduled
//more early, so you shuld use predication to check if condition happened
//and you'd better to use while() to check predication, for example:
//*****************************
//m_IsTaskRunMutex.Lock();
//while(!m_IsTaskRun)
// m_IsTaskRunCond.Wait(&m_IsTaskRunMutex,100);
//m_IsTaskRunMutex.Unlock();
//*****************************
void OSCond::Wait(OSMutex* inMutex, Int32 inTimeoutInMilSecs)
{
#ifdef __Win32__
DWORD theTimeout = INFINITE;
if (inTimeoutInMilSecs > 0)
theTimeout = inTimeoutInMilSecs;
fWaitCount++;
inMutex->Unlock();
DWORD theErr = ::WaitForSingleObject(fCondition, theTimeout);
Assert((theErr == WAIT_OBJECT_0) || (theErr == WAIT_TIMEOUT));
inMutex->Lock();
fWaitCount--;
#elif __PTHREADS_MUTEXES__
this->TimedWait(inMutex, inTimeoutInMilSecs);
#else
/*
Assert(fCondition != NULL);
mycondition_wait(fCondition, inMutex->fMutex, inTimeoutInMilSecs);
*/
#endif
}
/*
* 函数介绍:发信号。
* 使用前后应配合OSMutex::Lock,OSMutex::Unlock。
* 输入参数:无
* 输出参数:无
* 返回值 :无
*/
void OSCond::Signal()
{
#ifdef __Win32__
Bool theErr = ::SetEvent(fCondition);
Assert(theErr == TRUE);
#elif __PTHREADS_MUTEXES__
pthread_cond_signal(&fCondition);
#else
/*
Assert(fCondition != NULL);
mycondition_signal(fCondition);
*/#endif}/* * 函数介绍:发信号给阻塞在同一个OSCond的线程。 * 使用前后应配合OSMutex::Lock,OSMutex::Unlock。 * 输入参数:无 * 输出参数:无 * 返回值 :无 */void OSCond::Broadcast(){#ifdef __Win32__ // // There doesn't seem like any more elegant way to // implement Broadcast using events in Win32. // This will work, it may generate spurious wakeups, // but condition variables are allowed to generate // spurious wakeups UInt32 waitCount = fWaitCount; for (UInt32 x = 0; x < waitCount; x++) { Bool theErr = ::SetEvent(fCondition); Assert(theErr == TRUE); }#elif __PTHREADS_MUTEXES__ pthread_cond_broadcast(&fCondition);#else /* Assert(fCondition != NULL); mycondition_broadcast(fCondition); */
#endif
}/* * 函数介绍:等待 * 输入参数:inMutex - 互斥量 * inTimeoutInMilSecs - 0 :阻塞,直到有信号 * 非0:阻塞,直到有信号或inTimeoutInMilSecs微秒后超时 * 使用前后应配合OSMutex::Lock,OSMutex::Unlock。 * 输出参数:无 * 返回值 :无 */#if __PTHREADS_MUTEXES__void OSCond::TimedWait(OSMutex* inMutex, Int32 inTimeoutInMilSecs){ struct timespec ts; struct timeval tv; struct timezone tz; int sec, usec; //These platforms do refcounting manually, and wait will release the mutex, // so we need to update the counts here if (inTimeoutInMilSecs == 0) (void)pthread_cond_wait(&fCondition, &inMutex->fMutex); else { gettimeofday(&tv, &tz); sec = inTimeoutInMilSecs / 1000; inTimeoutInMilSecs = inTimeoutInMilSecs - (sec * 1000); Assert(inTimeoutInMilSecs < 1000); usec = inTimeoutInMilSecs * 1000; ts.tv_sec = tv.tv_sec + sec; ts.tv_nsec = (tv.tv_usec + usec) * 1000; Assert(ts.tv_nsec < 2000000000); if(ts.tv_nsec > 999999999) { ts.tv_sec++; ts.tv_nsec -= 1000000000; } (void)pthread_cond_timedwait(&fCondition, &inMutex->fMutex, &ts); } }
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -