⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 oscond.cpp

📁 跨操作系统的微型中间件
💻 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 + -