@@ -13,35 +13,57 @@ * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ +#include + bool of_condition_new(of_condition_t *condition) { condition->count = 0; - if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) + if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) { + errno = EAGAIN; return false; + } return true; } bool of_condition_signal(of_condition_t *condition) { - return SetEvent(condition->event); + if (!SetEvent(condition->event)) { + switch (GetLastError()) { + case ERROR_INVALID_HANDLE: + errno = EINVAL; + return false; + default: + OF_ENSURE(0); + } + } + + return true; } bool of_condition_broadcast(of_condition_t *condition) { int count = condition->count; - for (int i = 0; i < count; i++) - if (!SetEvent(condition->event)) - return false; + for (int i = 0; i < count; i++) { + if (!SetEvent(condition->event)) { + switch (GetLastError()) { + case ERROR_INVALID_HANDLE: + errno = EINVAL; + return false; + default: + OF_ENSURE(0); + } + } + } return true; } bool @@ -54,14 +76,24 @@ of_atomic_int_inc(&condition->count); status = WaitForSingleObject(condition->event, INFINITE); of_atomic_int_dec(&condition->count); - if (!of_mutex_lock(mutex)) - return false; - - return (status == WAIT_OBJECT_0); + switch (status) { + case WAIT_OBJECT_0: + return of_mutex_lock(mutex); + case WAIT_FAILED: + switch (GetLastError()) { + case ERROR_INVALID_HANDLE: + errno = EINVAL; + return false; + default: + OF_ENSURE(0); + } + default: + OF_ENSURE(0); + } } bool of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex, of_time_interval_t timeout) @@ -73,19 +105,34 @@ of_atomic_int_inc(&condition->count); status = WaitForSingleObject(condition->event, timeout * 1000); of_atomic_int_dec(&condition->count); - if (!of_mutex_lock(mutex)) + switch (status) { + case WAIT_OBJECT_0: + return of_mutex_lock(mutex); + case WAIT_TIMEOUT: + errno = ETIMEDOUT; return false; - - return (status == WAIT_OBJECT_0); + case WAIT_FAILED: + switch (GetLastError()) { + case ERROR_INVALID_HANDLE: + errno = EINVAL; + return false; + default: + OF_ENSURE(0); + } + default: + OF_ENSURE(0); + } } bool of_condition_free(of_condition_t *condition) { - if (condition->count != 0) + if (condition->count != 0) { + errno = EBUSY; return false; + } return CloseHandle(condition->event); }