1 /**
2 * \file
3 */
4
5 #ifndef _MONO_METADATA_W32HANDLE_H_
6 #define _MONO_METADATA_W32HANDLE_H_
7
8 #include <config.h>
9 #include <glib.h>
10
11 #ifdef HOST_WIN32
12 #include <windows.h>
13 #endif
14
15 #include "mono/utils/mono-coop-mutex.h"
16
17 #ifndef INVALID_HANDLE_VALUE
18 #define INVALID_HANDLE_VALUE (gpointer)-1
19 #endif
20
21 #define MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS 64
22
23 #ifndef MONO_INFINITE_WAIT
24 #define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
25 #endif
26
27 typedef enum {
28 MONO_W32TYPE_UNUSED = 0,
29 MONO_W32TYPE_SEM,
30 MONO_W32TYPE_MUTEX,
31 MONO_W32TYPE_EVENT,
32 MONO_W32TYPE_PROCESS,
33 MONO_W32TYPE_NAMEDMUTEX,
34 MONO_W32TYPE_NAMEDSEM,
35 MONO_W32TYPE_NAMEDEVENT,
36 MONO_W32TYPE_COUNT
37 } MonoW32Type;
38
39 typedef struct {
40 MonoW32Type type;
41 guint ref;
42 gboolean signalled;
43 gboolean in_use;
44 MonoCoopMutex signal_mutex;
45 MonoCoopCond signal_cond;
46 gpointer specific;
47 } MonoW32Handle;
48
49 typedef enum {
50 MONO_W32HANDLE_WAIT_RET_SUCCESS_0 = 0,
51 MONO_W32HANDLE_WAIT_RET_ABANDONED_0 = MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS,
52 MONO_W32HANDLE_WAIT_RET_ALERTED = -1,
53 MONO_W32HANDLE_WAIT_RET_TIMEOUT = -2,
54 MONO_W32HANDLE_WAIT_RET_FAILED = -3,
55 } MonoW32HandleWaitRet;
56
57 typedef struct
58 {
59 void (*close)(gpointer handle, gpointer data);
60
61 /* mono_w32handle_signal_and_wait */
62 void (*signal)(MonoW32Handle *handle_data);
63
64 /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
65 * with the handle locked (shared handles aren't locked.)
66 * Returns TRUE if ownership was established, false otherwise.
67 * If TRUE, *abandoned contains a status code such as
68 * WAIT_OBJECT_0 or WAIT_ABANDONED_0.
69 */
70 gboolean (*own_handle)(MonoW32Handle *handle_data, gboolean *abandoned);
71
72 /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple, if the
73 * handle in question is "ownable" (ie mutexes), to see if the current
74 * thread already owns this handle
75 */
76 gboolean (*is_owned)(MonoW32Handle *handle_data);
77
78 /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
79 * if the handle in question needs a special wait function
80 * instead of using the normal handle signal mechanism.
81 * Returns the mono_w32handle_wait_one return code.
82 */
83 MonoW32HandleWaitRet (*special_wait)(MonoW32Handle *handle_data, guint32 timeout, gboolean *alerted);
84
85 /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
86 * if the handle in question needs some preprocessing before the
87 * signal wait.
88 */
89 void (*prewait)(MonoW32Handle *handle_data);
90
91 /* Called when dumping the handles */
92 void (*details)(MonoW32Handle *handle_data);
93
94 /* Called to get the name of the handle type */
95 const gchar* (*typename) (void);
96
97 /* Called to get the size of the handle type */
98 gsize (*typesize) (void);
99 } MonoW32HandleOps;
100
101 typedef enum {
102 MONO_W32HANDLE_CAP_WAIT = 0x01,
103 MONO_W32HANDLE_CAP_SIGNAL = 0x02,
104 MONO_W32HANDLE_CAP_OWN = 0x04,
105 MONO_W32HANDLE_CAP_SPECIAL_WAIT = 0x08,
106 } MonoW32HandleCapability;
107
108 void
109 mono_w32handle_init (void);
110
111 void
112 mono_w32handle_cleanup (void);
113
114 void
115 mono_w32handle_register_ops (MonoW32Type type, MonoW32HandleOps *ops);
116
117 gpointer
118 mono_w32handle_new (MonoW32Type type, gpointer handle_specific);
119
120 gpointer
121 mono_w32handle_duplicate (MonoW32Handle *handle_data);
122
123 gboolean
124 mono_w32handle_close (gpointer handle);
125
126 const gchar*
127 mono_w32handle_get_typename (MonoW32Type type);
128
129 gboolean
130 mono_w32handle_lookup_and_ref (gpointer handle, MonoW32Handle **handle_data);
131
132 void
133 mono_w32handle_unref (MonoW32Handle *handle_data);
134
135 void
136 mono_w32handle_foreach (gboolean (*on_each)(MonoW32Handle *handle_data, gpointer user_data), gpointer user_data);
137
138 void
139 mono_w32handle_dump (void);
140
141 void
142 mono_w32handle_register_capabilities (MonoW32Type type, MonoW32HandleCapability caps);
143
144 void
145 mono_w32handle_set_signal_state (MonoW32Handle *handle_data, gboolean state, gboolean broadcast);
146
147 gboolean
148 mono_w32handle_issignalled (MonoW32Handle *handle_data);
149
150 void
151 mono_w32handle_lock (MonoW32Handle *handle_data);
152
153 gboolean
154 mono_w32handle_trylock (MonoW32Handle *handle_data);
155
156 void
157 mono_w32handle_unlock (MonoW32Handle *handle_data);
158
159 MonoW32HandleWaitRet
160 mono_w32handle_wait_one (gpointer handle, guint32 timeout, gboolean alertable);
161
162 MonoW32HandleWaitRet
163 mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waitall, guint32 timeout, gboolean alertable);
164
165 MonoW32HandleWaitRet
166 mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable);
167
168 #ifdef HOST_WIN32
169 static inline MonoW32HandleWaitRet
mono_w32handle_convert_wait_ret(guint32 res,guint32 numobjects)170 mono_w32handle_convert_wait_ret (guint32 res, guint32 numobjects)
171 {
172 if (res >= WAIT_OBJECT_0 && res <= WAIT_OBJECT_0 + numobjects - 1)
173 return MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + (res - WAIT_OBJECT_0);
174 else if (res >= WAIT_ABANDONED_0 && res <= WAIT_ABANDONED_0 + numobjects - 1)
175 return MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + (res - WAIT_ABANDONED_0);
176 else if (res == WAIT_IO_COMPLETION)
177 return MONO_W32HANDLE_WAIT_RET_ALERTED;
178 else if (res == WAIT_TIMEOUT)
179 return MONO_W32HANDLE_WAIT_RET_TIMEOUT;
180 else if (res == WAIT_FAILED)
181 return MONO_W32HANDLE_WAIT_RET_FAILED;
182 else
183 g_error ("%s: unknown res value %d", __func__, res);
184 }
185 #endif
186
187
188 #endif /* _MONO_METADATA_W32HANDLE_H_ */
189