code_app/modules/base/HGEvent.cpp

239 lines
4.4 KiB
C++

#include "HGEvent.h"
#include "HGInc.h"
#if !defined(HG_CMP_MSC)
typedef struct
{
HGBool state;
HGBool manual_reset;
pthread_mutex_t mutex;
pthread_cond_t cond;
}event_t, * event_handle;
#endif
HGResult HGAPI HGBase_CreateEvent(HGBool manualReset, HGBool initState, HGEvent* event)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
event_handle hEvent = new event_t;
hEvent->state = initState;
hEvent->manual_reset = manualReset;
if (0 != pthread_mutex_init(&hEvent->mutex, NULL))
{
delete hEvent;
return HGBASE_ERR_FAIL;
}
if (0 != pthread_cond_init(&hEvent->cond, NULL))
{
pthread_mutex_destroy(&hEvent->mutex);
delete hEvent;
return HGBASE_ERR_FAIL;
}
*event = (HGEvent)hEvent;
#else
HANDLE hEvent = CreateEventW(NULL, (BOOL)manualReset, (BOOL)initState, NULL);
*event = (HGEvent)hEvent;
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_DestroyEvent(HGEvent event)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
event_handle hEvent = (event_handle)event;
pthread_cond_destroy(&hEvent->cond);
pthread_mutex_destroy(&hEvent->mutex);
delete hEvent;
#else
HANDLE hEvent = (HANDLE)event;
CloseHandle(hEvent);
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_WaitEvent(HGEvent event)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
event_handle hEvent = (event_handle)event;
if (0 != pthread_mutex_lock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
while (!hEvent->state)
{
if (0 != pthread_cond_wait(&hEvent->cond, &hEvent->mutex))
{
pthread_mutex_unlock(&hEvent->mutex);
return HGBASE_ERR_FAIL;
}
}
if (!hEvent->manual_reset)
{
hEvent->state = HGFALSE;
}
if (0 != pthread_mutex_unlock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
#else
HANDLE hEvent = (HANDLE)event;
DWORD ret = WaitForSingleObject(hEvent, INFINITE);
if (WAIT_OBJECT_0 != ret)
{
return HGBASE_ERR_FAIL;
}
#endif
return HGBASE_ERR_OK;
}
HGResult HGAPI HGBase_WaitEventTimeout(HGEvent event, HGUInt milliseconds)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
struct timespec abstime;
struct timeval tv;
gettimeofday(&tv, NULL);
abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
abstime.tv_nsec = tv.tv_usec * 1000 + (milliseconds % 1000) * 1000000;
if (abstime.tv_nsec >= 1000000000)
{
abstime.tv_nsec -= 1000000000;
abstime.tv_sec++;
}
int rc = 0;
event_handle hEvent = (event_handle)event;
if (pthread_mutex_lock(&hEvent->mutex) != 0)
{
return HGBASE_ERR_FAIL;
}
while (!hEvent->state)
{
rc = pthread_cond_timedwait(&hEvent->cond, &hEvent->mutex, &abstime);
if (0 != rc)
{
if (rc == ETIMEDOUT)
break;
pthread_mutex_unlock(&hEvent->mutex);
return HGBASE_ERR_FAIL;
}
}
if (rc == 0 && !hEvent->manual_reset)
{
hEvent->state = HGFALSE;
}
if (pthread_mutex_unlock(&hEvent->mutex) != 0)
{
return HGBASE_ERR_FAIL;
}
if (rc == ETIMEDOUT)
{
return HGBASE_ERR_TIMEOUT;
}
return HGBASE_ERR_OK;
#else
HANDLE hEvent = (HANDLE)event;
DWORD ret = WaitForSingleObject(hEvent, milliseconds);
if (WAIT_OBJECT_0 == ret)
{
return HGBASE_ERR_OK;
}
else if (WAIT_TIMEOUT == ret)
{
return HGBASE_ERR_TIMEOUT;
}
return HGBASE_ERR_FAIL;
#endif
}
HGResult HGAPI HGBase_SetEvent(HGEvent event)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
event_handle hEvent = (event_handle)event;
if (0 != pthread_mutex_lock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
hEvent->state = HGTRUE;
if (hEvent->manual_reset)
{
if (0 != pthread_cond_broadcast(&hEvent->cond))
{
pthread_mutex_unlock(&hEvent->mutex);
return HGBASE_ERR_FAIL;
}
}
else
{
if (0 != pthread_cond_signal(&hEvent->cond))
{
pthread_mutex_unlock(&hEvent->mutex);
return HGBASE_ERR_FAIL;
}
}
if (0 != pthread_mutex_unlock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
return HGBASE_ERR_OK;
#else
HANDLE hEvent = (HANDLE)event;
SetEvent(hEvent);
return HGBASE_ERR_OK;
#endif
}
HGResult HGAPI HGBase_ResetEvent(HGEvent event)
{
if (NULL == event)
{
return HGBASE_ERR_INVALIDARG;
}
#if !defined(HG_CMP_MSC)
event_handle hEvent = (event_handle)event;
if (0 != pthread_mutex_lock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
hEvent->state = HGFALSE;
if (0 != pthread_mutex_unlock(&hEvent->mutex))
{
return HGBASE_ERR_FAIL;
}
return HGBASE_ERR_OK;
#else
HANDLE hEvent = (HANDLE)event;
ResetEvent(hEvent);
return HGBASE_ERR_OK;
#endif
}