MemoryMappedFile support on Windows
[mono.git] / mono / io-layer / wait.c
1 /*
2  * wait.c:  wait for handles to become signalled
3  *
4  * Author:
5  *      Dick Porter (dick@ximian.com)
6  *
7  * (C) 2002-2006 Novell, Inc.
8  */
9
10 #include <config.h>
11 #include <glib.h>
12 #include <string.h>
13 #include <errno.h>
14
15 #include <mono/io-layer/wapi.h>
16 #include <mono/io-layer/wapi-private.h>
17 #include <mono/utils/w32handle.h>
18
19 /**
20  * WaitForSingleObjectEx:
21  * @handle: an object to wait for
22  * @timeout: the maximum time in milliseconds to wait for
23  * @alertable: if TRUE, the wait can be interrupted by an APC call
24  *
25  * This function returns when either @handle is signalled, or @timeout
26  * ms elapses.  If @timeout is zero, the object's state is tested and
27  * the function returns immediately.  If @timeout is %INFINITE, the
28  * function waits forever.
29  *
30  * Return value: %WAIT_ABANDONED - @handle is a mutex that was not
31  * released by the owning thread when it exited.  Ownership of the
32  * mutex object is granted to the calling thread and the mutex is set
33  * to nonsignalled.  %WAIT_OBJECT_0 - The state of @handle is
34  * signalled.  %WAIT_TIMEOUT - The @timeout interval elapsed and
35  * @handle's state is still not signalled.  %WAIT_FAILED - an error
36  * occurred. %WAIT_IO_COMPLETION - the wait was ended by an APC.
37  */
38 guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, gboolean alertable)
39 {
40         MonoW32HandleWaitRet ret;
41
42         ret = mono_w32handle_wait_one (handle, timeout, alertable);
43         if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
44                 return WAIT_OBJECT_0;
45         else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
46                 return WAIT_ABANDONED_0;
47         else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
48                 return WAIT_IO_COMPLETION;
49         else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
50                 return WAIT_TIMEOUT;
51         else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
52                 return WAIT_FAILED;
53         else
54                 g_error ("%s: unknown ret value %d", __func__, ret);
55 }
56
57
58 /**
59  * SignalObjectAndWait:
60  * @signal_handle: An object to signal
61  * @wait: An object to wait for
62  * @timeout: The maximum time in milliseconds to wait for
63  * @alertable: Specifies whether the function returnes when the system
64  * queues an I/O completion routine or an APC for the calling thread.
65  *
66  * Atomically signals @signal and waits for @wait to become signalled,
67  * or @timeout ms elapses.  If @timeout is zero, the object's state is
68  * tested and the function returns immediately.  If @timeout is
69  * %INFINITE, the function waits forever.
70  *
71  * @signal can be a semaphore, mutex or event object.
72  *
73  * If @alertable is %TRUE and the system queues an I/O completion
74  * routine or an APC for the calling thread, the function returns and
75  * the thread calls the completion routine or APC function.  If
76  * %FALSE, the function does not return, and the thread does not call
77  * the completion routine or APC function.  A completion routine is
78  * queued when the ReadFileEx() or WriteFileEx() function in which it
79  * was specified has completed.  The calling thread is the thread that
80  * initiated the read or write operation.  An APC is queued when
81  * QueueUserAPC() is called.  Currently completion routines and APC
82  * functions are not supported.
83  *
84  * Return value: %WAIT_ABANDONED - @wait is a mutex that was not
85  * released by the owning thread when it exited.  Ownershop of the
86  * mutex object is granted to the calling thread and the mutex is set
87  * to nonsignalled.  %WAIT_IO_COMPLETION - the wait was ended by one
88  * or more user-mode asynchronous procedure calls queued to the
89  * thread.  %WAIT_OBJECT_0 - The state of @wait is signalled.
90  * %WAIT_TIMEOUT - The @timeout interval elapsed and @wait's state is
91  * still not signalled.  %WAIT_FAILED - an error occurred.
92  */
93 guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
94                             guint32 timeout, gboolean alertable)
95 {
96         MonoW32HandleWaitRet ret;
97
98         ret = mono_w32handle_signal_and_wait (signal_handle, wait, timeout, alertable);
99         if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
100                 return WAIT_OBJECT_0;
101         else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
102                 return WAIT_ABANDONED_0;
103         else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
104                 return WAIT_IO_COMPLETION;
105         else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
106                 return WAIT_TIMEOUT;
107         else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
108                 return WAIT_FAILED;
109         else
110                 g_error ("%s: unknown ret value %d", __func__, ret);
111 }
112
113 /**
114  * WaitForMultipleObjectsEx:
115  * @numobjects: The number of objects in @handles. The maximum allowed
116  * is %MAXIMUM_WAIT_OBJECTS.
117  * @handles: An array of object handles.  Duplicates are not allowed.
118  * @waitall: If %TRUE, this function waits until all of the handles
119  * are signalled.  If %FALSE, this function returns when any object is
120  * signalled.
121  * @timeout: The maximum time in milliseconds to wait for.
122  * @alertable: if TRUE, the wait can be interrupted by an APC call
123  * 
124  * This function returns when either one or more of @handles is
125  * signalled, or @timeout ms elapses.  If @timeout is zero, the state
126  * of each item of @handles is tested and the function returns
127  * immediately.  If @timeout is %INFINITE, the function waits forever.
128  *
129  * Return value: %WAIT_OBJECT_0 to %WAIT_OBJECT_0 + @numobjects - 1 -
130  * if @waitall is %TRUE, indicates that all objects are signalled.  If
131  * @waitall is %FALSE, the return value minus %WAIT_OBJECT_0 indicates
132  * the first index into @handles of the objects that are signalled.
133  * %WAIT_ABANDONED_0 to %WAIT_ABANDONED_0 + @numobjects - 1 - if
134  * @waitall is %TRUE, indicates that all objects are signalled, and at
135  * least one object is an abandoned mutex object (See
136  * WaitForSingleObject() for a description of abandoned mutexes.)  If
137  * @waitall is %FALSE, the return value minus %WAIT_ABANDONED_0
138  * indicates the first index into @handles of an abandoned mutex.
139  * %WAIT_TIMEOUT - The @timeout interval elapsed and no objects in
140  * @handles are signalled.  %WAIT_FAILED - an error occurred.
141  * %WAIT_IO_COMPLETION - the wait was ended by an APC.
142  */
143 guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
144                                  gboolean waitall, guint32 timeout,
145                                  gboolean alertable)
146 {
147         MonoW32HandleWaitRet ret;
148
149         ret = mono_w32handle_wait_multiple (handles, numobjects, waitall, timeout, alertable);
150         if (ret >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 && ret <= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + numobjects - 1)
151                 return WAIT_OBJECT_0 + (ret - MONO_W32HANDLE_WAIT_RET_SUCCESS_0);
152         else if (ret >= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 && ret <= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + numobjects - 1)
153                 return WAIT_ABANDONED_0 + (ret - MONO_W32HANDLE_WAIT_RET_ABANDONED_0);
154         else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
155                 return WAIT_IO_COMPLETION;
156         else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
157                 return WAIT_TIMEOUT;
158         else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
159                 return WAIT_FAILED;
160         else
161                 g_error ("%s: unknown ret value %d", __func__, ret);
162 }
163