Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / utils / os-event-win32.c
1 /**
2  * \file
3  * MonoOSEvent on Win32
4  *
5  * Author:
6  *      Ludovic Henry (luhenry@microsoft.com)
7  *
8  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9  */
10
11 #include "os-event.h"
12
13 #include <windows.h>
14 #include <winbase.h>
15
16 #include "atomic.h"
17 #include "mono-os-wait.h"
18
19 void
20 mono_os_event_init (MonoOSEvent *event, gboolean initial)
21 {
22         g_assert (event);
23
24         event->handle = CreateEvent (NULL, TRUE, initial, NULL);
25         if (G_UNLIKELY (!event->handle))
26                 g_error ("%s: CreateEvent failed with error %d", __func__, GetLastError ());
27 }
28
29 void
30 mono_os_event_destroy (MonoOSEvent *event)
31 {
32         BOOL res;
33
34         g_assert (event);
35         g_assert (event->handle);
36
37         res = CloseHandle (event->handle);
38         if (G_UNLIKELY (res == 0))
39                 g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
40 }
41
42 void
43 mono_os_event_set (MonoOSEvent *event)
44 {
45         BOOL res;
46
47         g_assert (event);
48         g_assert (event->handle);
49
50         res = SetEvent (event->handle);
51         if (G_UNLIKELY (res == 0))
52                 g_error ("%s: SetEvent failed with error %d", __func__, GetLastError ());
53 }
54
55 void
56 mono_os_event_reset (MonoOSEvent *event)
57 {
58         BOOL res;
59
60         g_assert (event);
61         g_assert (event->handle);
62
63         res = ResetEvent (event->handle);
64         if (G_UNLIKELY (res == 0))
65                 g_error ("%s: ResetEvent failed with error %d", __func__, GetLastError ());
66 }
67
68 MonoOSEventWaitRet
69 mono_os_event_wait_one (MonoOSEvent *event, guint32 timeout, gboolean alertable)
70 {
71         DWORD res;
72
73         g_assert (event);
74         g_assert (event->handle);
75
76         res = mono_win32_wait_for_single_object_ex (event->handle, timeout, alertable);
77         if (res == WAIT_OBJECT_0)
78                 return MONO_OS_EVENT_WAIT_RET_SUCCESS_0;
79         else if (res == WAIT_IO_COMPLETION)
80                 return MONO_OS_EVENT_WAIT_RET_ALERTED;
81         else if (res == WAIT_TIMEOUT)
82                 return MONO_OS_EVENT_WAIT_RET_TIMEOUT;
83         else if (res == WAIT_FAILED)
84                 g_error ("%s: mono_thread_win32_wait_one_handle failed with error %d", __func__, GetLastError ());
85         else
86                 g_error ("%s: unknown res value %d", __func__, res);
87 }
88
89 MonoOSEventWaitRet
90 mono_os_event_wait_multiple (MonoOSEvent **events, gsize nevents, gboolean waitall, guint32 timeout, gboolean alertable)
91 {
92         DWORD res;
93         gpointer handles [MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS];
94         gint i;
95
96         g_assert (events);
97         g_assert (nevents > 0);
98         g_assert (nevents <= MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS);
99
100         if (nevents == 1)
101                 return mono_os_event_wait_one (events [0], timeout, alertable);
102
103         for (i = 0; i < nevents; ++i) {
104                 g_assert (events [i]);
105                 g_assert (events [i]->handle);
106                 handles [i] = events [i]->handle;
107         }
108
109         res = mono_win32_wait_for_multiple_objects_ex ((DWORD)nevents, handles, waitall, timeout, alertable);
110         if (res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_0 + MONO_OS_EVENT_WAIT_MAXIMUM_OBJECTS)
111                 return MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + (res - WAIT_OBJECT_0);
112         else if (res == WAIT_IO_COMPLETION)
113                 return MONO_OS_EVENT_WAIT_RET_ALERTED;
114         else if (res == WAIT_TIMEOUT)
115                 return MONO_OS_EVENT_WAIT_RET_TIMEOUT;
116         else if (res == WAIT_FAILED)
117                 g_error ("%s: mono_thread_win32_wait_multiple_handle failed with error %d", __func__, GetLastError ());
118         else
119                 g_error ("%s: unknown res value %d", __func__, res);
120 }