#include "HGEvent.h" #include "HGInc.h" #if !defined(HG_CMP_MSC) struct event_t { HGBool state; HGBool manual_reset; pthread_mutex_t mutex; pthread_cond_t cond; }; #endif HGResult HGAPI HGBase_CreateEvent(HGBool manualReset, HGBool initState, HGEvent* event) { if (NULL == event) { return HGBASE_ERR_INVALIDARG; } #if !defined(HG_CMP_MSC) event_t* 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_t* hEvent = (event_t*)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_t* hEvent = (event_t*)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_t* hEvent = (event_t*)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_t* hEvent = (event_t*)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_t* hEvent = (event_t*)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 }