/** * \file * MonoOSEvent on Win32 * * Author: * Ludovic Henry (luhenry@microsoft.com) * * Licensed under the MIT license. See LICENSE file in the project root for full license information. */ #include "os-event.h" #include #include #include "atomic.h" #include "mono-os-wait.h" void mono_os_event_init (MonoOSEvent *event, gboolean initial) { g_assert (event); event->handle = CreateEvent (NULL, TRUE, initial, NULL); if (G_UNLIKELY (!event->handle)) g_error ("%s: CreateEvent failed with error %d", __func__, GetLastError ()); } void mono_os_event_destroy (MonoOSEvent *event) { BOOL res; g_assert (event); g_assert (event->handle); res = CloseHandle (event->handle); if (G_UNLIKELY (res == 0)) g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ()); } void mono_os_event_set (MonoOSEvent *event) { BOOL res; g_assert (event); g_assert (event->handle); res = SetEvent (event->handle); if (G_UNLIKELY (res == 0)) g_error ("%s: SetEvent failed with error %d", __func__, GetLastError ()); } void mono_os_event_reset (MonoOSEvent *event) { BOOL res; g_assert (event); g_assert (event->handle); res = ResetEvent (event->handle); if (G_UNLIKELY (res == 0)) g_error ("%s: ResetEvent failed with error %d", __func__, GetLastError ()); } MonoOSEventWaitRet mono_os_event_wait_one (MonoOSEvent *event, guint32 timeout, gboolean alertable) { DWORD res; g_assert (event); g_assert (event->handle); res = mono_win32_wait_for_single_object_ex (event->handle, timeout, alertable); if (res == WAIT_OBJECT_0) return MONO_OS_EVENT_WAIT_RET_SUCCESS_0; else if (res == WAIT_IO_COMPLETION) return MONO_OS_EVENT_WAIT_RET_ALERTED; else if (res == WAIT_TIMEOUT) return MONO_OS_EVENT_WAIT_RET_TIMEOUT; else if (res == WAIT_FAILED) g_error ("%s: mono_thread_win32_wait_one_handle failed with error %d", __func__, GetLastError ()); else g_error ("%s: unknown res value %d", __func__, res); } MonoOSEventWaitRet mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waitall, guint32 timeout, gboolean alertable) { DWORD res; gpointer handles [MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS]; gint i; g_assert (events); g_assert (nevents > 0); g_assert (nevents <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS); if (nevents == 1) return mono_os_event_wait_one (events [0], timeout, alertable); for (i = 0; i < nevents; ++i) { g_assert (events [i]); g_assert (events [i]->handle); handles [i] = events [i]->handle; } res = mono_win32_wait_for_multiple_objects_ex ((DWORD)nevents, handles, waitall, timeout, alertable); if (res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_0 + MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS) return MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + (res - WAIT_OBJECT_0); else if (res == WAIT_IO_COMPLETION) return MONO_OS_EVENT_WAIT_RET_ALERTED; else if (res == WAIT_TIMEOUT) return MONO_OS_EVENT_WAIT_RET_TIMEOUT; else if (res == WAIT_FAILED) g_error ("%s: mono_thread_win32_wait_multiple_handle failed with error %d", __func__, GetLastError ()); else g_error ("%s: unknown res value %d", __func__, res); }