/***********************************************************
*Date:2016-07-19
*
*Author:牟韵
*
*Department:智能产品中心-研发部
*
*Company:北京海鑫科金高科技股份有限公司
*
*Module: 平台事件
*
*CodePage:Pure UTF-8
************************************************************/
#ifndef __OS_EVENT_HPP_BY_MOUYUN_2016_07_19__
#define __OS_EVENT_HPP_BY_MOUYUN_2016_07_19__
#include "platform_select.hpp"
#if PLATFORM_WINDOWS
#include <Windows.h>
#elif PLATFORM_LINUX
#include <pthread.h>
#include <sys/time.h>
#include <errno.h>
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
#define OS_EVENT_INFINITE_WAIT_TIME (-1) /// < 无限等待的时间值
typedef enum _OSEventResultEnum
{
OS_ER_FAIL = (-1),
OS_ER_SUCCESS = 0,
OS_ER_TIME_OUT
}OSEventResult;
class COSEvent
{
private:
#if PLATFORM_WINDOWS
typedef HANDLE os_event;
#elif PLATFORM_LINUX
class CLinuxEventWrapper
{
public:
bool m_state;
bool m_manual_reset;
pthread_mutex_t m_mutex;
pthread_cond_t m_cond;
};
typedef CLinuxEventWrapper os_event;
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
public:
COSEvent(bool manual_reset = true, bool init_state = false)
{
#if PLATFORM_WINDOWS
m_event = ::CreateEvent(NULL, manual_reset, init_state, NULL);
#elif PLATFORM_LINUX
m_event.m_state = init_state;
m_event.m_manual_reset = manual_reset;
if (0 == pthread_mutex_init(&m_event.m_mutex, 0))
{
if (0 != pthread_cond_init(&m_event.m_cond, 0))
{
pthread_mutex_destroy(&m_event.m_mutex);
}
}
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
}
~COSEvent()
{
#if PLATFORM_WINDOWS
if (NULL != m_event)
{
::CloseHandle(m_event);
m_event = NULL;
}
#elif PLATFORM_LINUX
pthread_cond_destroy(&m_event.m_cond);
pthread_mutex_destroy(&m_event.m_mutex);
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
}
private:
COSEvent(const COSEvent&);
COSEvent& operator=(const COSEvent&);
public:
/// < _ms传递负值表示无限等待,否则是带超时的等待
int wait(const int _ms = OS_EVENT_INFINITE_WAIT_TIME)
{
#if PLATFORM_WINDOWS
DWORD wait_time = 0 > _ms ? INFINITE : _ms;
DWORD _result = ::WaitForSingleObject(m_event, wait_time);
if (WAIT_OBJECT_0 == _result)
{
return OS_ER_SUCCESS;
}
if (WAIT_TIMEOUT == _result)
{
return OS_ER_TIME_OUT;
}
else
{
return OS_ER_FAIL;
}
#elif PLATFORM_LINUX
int _result = 0;
if (0 > _ms)
{
if (0 != pthread_mutex_lock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
while (!m_event.m_state)
{
if (0 != pthread_cond_wait(&m_event.m_cond, &m_event.m_mutex))
{
pthread_mutex_unlock(&m_event.m_mutex);
return OS_ER_FAIL;
}
}
if (!m_event.m_manual_reset)
{
m_event.m_state = false;
}
if (0 != pthread_mutex_unlock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
return OS_ER_SUCCESS;
}
struct timespec ab_time;
struct timeval cur_time;
if (0 != gettimeofday(&cur_time, 0))
{
return OS_ER_FAIL;
}
ab_time.tv_sec = cur_time.tv_sec;
ab_time.tv_nsec = cur_time.tv_usec * 1000;
long long _ns = static_cast<long long>(ab_time.tv_nsec) + (static_cast<long long>(_ms) * 1000000);
ab_time.tv_sec += _ns / 1000000000;
ab_time.tv_nsec = _ns % 1000000000;
if (0 != pthread_mutex_lock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
while (!m_event.m_state)
{
_result = pthread_cond_timedwait(&m_event.m_cond, &m_event.m_mutex, &ab_time);
if (0 != _result)
{
if (ETIMEDOUT == _result)
{
break;
}
else
{
pthread_mutex_unlock(&m_event.m_mutex);
return OS_ER_FAIL;
}
}
}
if (0 == _result && !m_event.m_manual_reset)
{
m_event.m_state = false;
}
if (0 != pthread_mutex_unlock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
if (ETIMEDOUT == _result)
{
return OS_ER_TIME_OUT;
}
else
{
return OS_ER_SUCCESS;
}
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
}
int set()
{
#if PLATFORM_WINDOWS
if (FALSE != ::SetEvent(m_event))
{
return OS_ER_SUCCESS;
}
else
{
return OS_ER_FAIL;
}
#elif PLATFORM_LINUX
if (0 != pthread_mutex_lock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
m_event.m_state = true;
if (m_event.m_manual_reset)
{
if (0 != pthread_cond_broadcast(&m_event.m_cond))
{
pthread_mutex_unlock(&m_event.m_mutex);
return OS_ER_FAIL;
}
}
else
{
if (0 != pthread_cond_signal(&m_event.m_cond))
{
pthread_mutex_unlock(&m_event.m_mutex);
return OS_ER_FAIL;
}
}
if (0 != pthread_mutex_unlock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
return OS_ER_SUCCESS;
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
}
int reset()
{
#if PLATFORM_WINDOWS
if (FALSE != ::ResetEvent(m_event))
{
return OS_ER_SUCCESS;
}
else
{
return OS_ER_FAIL;
}
#elif PLATFORM_LINUX
if (0 != pthread_mutex_lock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
m_event.m_state = false;
if (0 != pthread_mutex_unlock(&m_event.m_mutex))
{
return OS_ER_FAIL;
}
return OS_ER_SUCCESS;
#else
#error Specified platform is invalid! Please check macro in file platform_select.hpp.
#endif
}
private:
os_event m_event;
};
#endif
评论0
最新资源