23,223
社区成员
发帖
与我相关
我的任务
分享
int MC_KKEvent::WaitFinite(UINT32 vMillisecond)
{
pthread_mutex_lock(&m_Mutex);
/*
timespec.tv_sec //秒
timespec.tv_nsec //纳秒
timeval.tv_sec //秒
timeval.tv_usec //微妙
*/
struct timespec tAbstime;
struct timeval tTimeNow;
gettimeofday(&tTimeNow, 0);
tAbstime.tv_sec = tTimeNow.tv_sec + vMillisecond/1000;
tAbstime.tv_nsec = tTimeNow.tv_usec*1000 + (vMillisecond%1000)*1000000;
//纳米变为秒
const long BILLION = 1000000000;
if(BILLION <= tAbstime.tv_nsec)
{
tAbstime.tv_nsec -= BILLION;
tAbstime.tv_sec++;
}
int tRetVal = KKEVENT_SIGNALED;
while(false == m_State)
{
//收到外部中断退出
if(true == m_Break)
{
tRetVal = KKEVENT_FAILED;
break;
}
int tResult = pthread_cond_timedwait(&m_Cond, &m_Mutex, &tAbstime);
if((0 != tResult)&&(ETIMEDOUT != tResult))
{
tRetVal = KKEVENT_FAILED;
break;
}
//超时
if(ETIMEDOUT==tResult)
{
tRetVal = KKEVENT_TIMEOUT;
break;
}
}
//收到外部中断退出
if(true == m_Break)
tRetVal = KKEVENT_FAILED;
//若为自动置为事件,则置状态为false
if(false == m_ManualReset)
m_State = false;
pthread_mutex_unlock(&m_Mutex);
return tRetVal;
}
pthread_mutex_t tMutex;
pthread_mutex_init(&tMutex, 0);
pthread_mutex_unlock(&tMutex); //这里故意搞破坏
pthread_cond_t tCond;
pthread_cond_init(&tCond, 0);
struct timespec tAbstime;
struct timeval tTimeNow;
gettimeofday(&tTimeNow, 0);
tAbstime.tv_sec = tTimeNow.tv_sec;
tAbstime.tv_nsec = tTimeNow.tv_usec*1000;
//这里仍然立刻返回,错误吗110,ETIMEOUT
int tRetVal = pthread_condpthread_mutex_lock(&m_Mutex);
m_State = true;
if(true == m_ManualReset)
tResult = (0 == pthread_cond_broadcast(&m_Cond));
else
tResult = (0 == pthread_cond_signal(&m_Cond));
pthread_mutex_unlock(&m_Mutex);
改为
pthread_mutex_lock(&m_Mutex);
m_State = true;
pthread_mutex_unlock(&m_Mutex);
if(true == m_ManualReset)
tResult = (0 == pthread_cond_broadcast(&m_Cond));
else
tResult = (0 == pthread_cond_signal(&m_Cond));
试试
//---------------------------------------------------------------------------
#ifndef MC_KKEventH
#define MC_KKEventH
//---------------------------------------------------------------------------
#include "ZAVXShareIncLib.h"
//---------------------------------------------------------------------------
#define KKEVENT_SIGNALED 0
#define KKEVENT_FAILED -1
#define KKEVENT_TIMEOUT -2
//---------------------------------------------------------------------------
#ifdef WIN32
#define KKEVENT_INFINITE INFINITE
#else
#define KKEVENT_INFINITE (UINT32)-1
#endif
//---------------------------------------------------------------------------
class MC_KKEvent
{
private:
#ifdef WIN32
HANDLE m_HandleWait[2];
#else
int WaitInfinite (void);
int WaitFinite (UINT32 vMillisecond);
pthread_mutex_t m_Mutex;
pthread_cond_t m_Cond;
bool m_State; //linux实现自动置位的标志
bool m_Break; //外部调用Close的停止标志
#endif
bool m_ManualReset;
public:
MC_KKEvent(bool vState=false, bool vManualReset=false);
~MC_KKEvent(void);
int Wait (UINT32 vMillisecond=KKEVENT_INFINITE);
bool Signaled (void);
bool Nonsignaled (void);
bool Close (void); //调用此函数,将导致之前所有的Wait会返回KKEVENT_FAILED, 之后本身将不可再使用.
bool m_Available;
};
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include "MC_KKEvent.h"
#include "MF_KKKernelFunc.h"
#ifndef WIN32
#include <sys/time.h>
#include <errno.h>
#endif
//---------------------------------------------------------------------------`
MC_KKEvent::MC_KKEvent(bool vState, bool vManualReset)
{
m_Available = false;
#ifdef WIN32
m_HandleWait[0] = CreateEvent(0, vManualReset, vState, 0);
if(0 == m_HandleWait[0])
return;
m_HandleWait[1] = CreateEvent(0, true, false, 0);
if(0 == m_HandleWait[1])
return;
m_ManualReset = vManualReset;
#else
if(0 != pthread_mutex_init(&m_Mutex, 0))
return;
if(0 != pthread_cond_init(&m_Cond, 0))
{
pthread_mutex_destroy(&m_Mutex);
return;
}
m_State = vState;
m_ManualReset = vManualReset;
m_Break = false;
#endif
m_Available = true;
}
//---------------------------------------------------------------------------
MC_KKEvent::~MC_KKEvent(void)
{
if(false == m_Available)
return;
#ifdef WIN32
avx_SafeCloseH(m_HandleWait[0]);
avx_SafeCloseH(m_HandleWait[1]);
#else
pthread_mutex_destroy(&m_Mutex);
pthread_cond_destroy(&m_Cond);
#endif
m_Available = false;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef WIN32
int MC_KKEvent::WaitInfinite(void)
{
pthread_mutex_lock(&m_Mutex);
int tRetVal = KKEVENT_SIGNALED;
while(false == m_State)
{
//收到外部中断退出
if(true == m_Break)
{
tRetVal = KKEVENT_FAILED;
break;
}
if(0 != pthread_cond_wait(&m_Cond, &m_Mutex))
{
tRetVal = KKEVENT_FAILED;
break;
}
}
//收到外部中断退出
if(true == m_Break)
tRetVal = KKEVENT_FAILED;
//若为自动置为事件,则置状态为false
if(false == m_ManualReset)
m_State = false;
pthread_mutex_unlock(&m_Mutex);
return tRetVal;
}
//---------------------------------------------------------------------------
int MC_KKEvent::WaitFinite(UINT32 vMillisecond)
{
pthread_mutex_lock(&m_Mutex);
/*
timespec.tv_sec //秒
timespec.tv_nsec //纳秒
timeval.tv_sec //秒
timeval.tv_usec //微妙
*/
struct timespec tAbstime;
struct timeval tTimeNow;
gettimeofday(&tTimeNow, 0);
tAbstime.tv_sec = tTimeNow.tv_sec + vMillisecond/1000;
tAbstime.tv_nsec = tTimeNow.tv_usec*1000 + (vMillisecond%1000)*1000000;
//纳米变为秒
const long BILLION = 1000000000;
if(BILLION <= tAbstime.tv_nsec)
{
tAbstime.tv_nsec -= BILLION;
tAbstime.tv_sec++;
}
int tRetVal = KKEVENT_SIGNALED;
while(false == m_State)
{
//收到外部中断退出
if(true == m_Break)
{
tRetVal = KKEVENT_FAILED;
break;
}
int tResult = pthread_cond_timedwait(&m_Cond, &m_Mutex, &tAbstime);
if((0 != tResult)&&(ETIMEDOUT != tResult))
{
tRetVal = KKEVENT_FAILED;
break;
}
//超时
if(ETIMEDOUT==tResult)
{
tRetVal = KKEVENT_TIMEOUT;
break;
}
}
//收到外部中断退出
if(true == m_Break)
tRetVal = KKEVENT_FAILED;
//若为自动置为事件,则置状态为false
if(false == m_ManualReset)
m_State = false;
pthread_mutex_unlock(&m_Mutex);
return tRetVal;
}
#endif
//---------------------------------------------------------------------------
int MC_KKEvent::Wait(UINT32 vMillisecond)
{
if(false == m_Available)
return KKEVENT_FAILED;
#ifdef WIN32
UINT32 tWaitRet = WaitForMultipleObjects(2, m_HandleWait, false, vMillisecond);
switch(tWaitRet)
{
case WAIT_TIMEOUT: return KKEVENT_TIMEOUT;
case WAIT_OBJECT_0: return KKEVENT_SIGNALED;
default: return KKEVENT_FAILED;
}
#else
if((UINT32)-1 == vMillisecond)
return WaitInfinite();
else
return WaitFinite(vMillisecond);
#endif
}
//---------------------------------------------------------------------------
bool MC_KKEvent::Signaled(void)
{
if(false == m_Available)
return false;
bool tResult = false;
#ifdef WIN32
if(false != SetEvent(m_HandleWait[0]))
tResult = true;
#else
pthread_mutex_lock(&m_Mutex);
m_State = true;
if(true == m_ManualReset)
tResult = (0 == pthread_cond_broadcast(&m_Cond));
else
tResult = (0 == pthread_cond_signal(&m_Cond));
pthread_mutex_unlock(&m_Mutex);
#endif
return tResult;
}
//---------------------------------------------------------------------------
bool MC_KKEvent::Nonsignaled(void)
{
if(false == m_Available)
return false;
#ifdef WIN32
if(false != ResetEvent(m_HandleWait[0]))
return true;
return false;
#else
pthread_mutex_lock(&m_Mutex);
m_State = false;
pthread_mutex_unlock(&m_Mutex);
return true;
#endif
}
//---------------------------------------------------------------------------
bool MC_KKEvent::Close(void)
{
if(false == m_Available)
return false;
#ifdef WIN32
if(false == SetEvent(m_HandleWait[1]))
return false;
#else
m_Break = true;
pthread_cond_broadcast(&m_Cond);
#endif
this->~MC_KKEvent();
return true;
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
bool MC_KKEvent::Signaled(void)
{
if(false == m_Available)
return false;
bool tResult = false;
pthread_mutex_lock(&m_Mutex);
m_State = true;
if(true == m_ManualReset)
tResult = (0 == pthread_cond_broadcast(&m_Cond));
else
tResult = (0 == pthread_cond_signal(&m_Cond));
pthread_mutex_unlock(&m_Mutex);
return tResult;
}
//---------------------------------------------------------------------------
bool MC_KKEvent::Nonsignaled(void)
{
if(false == m_Available)
return false;
pthread_mutex_lock(&m_Mutex);
m_State = false;
pthread_mutex_unlock(&m_Mutex);
return true;
}
//---------------------------------------------------------------------------