#undef DEBUG
-static void event_close_shared (gpointer handle);
static void event_signal(gpointer handle);
-static void event_own (gpointer handle);
+static gboolean event_own (gpointer handle);
+
+static void namedevent_signal (gpointer handle);
+static gboolean namedevent_own (gpointer handle);
struct _WapiHandleOps _wapi_event_ops = {
- event_close_shared, /* close_shared */
- NULL, /* close_private */
+ NULL, /* close */
event_signal, /* signal */
event_own, /* own */
NULL, /* is_owned */
+ NULL, /* special_wait */
+ NULL /* prewait */
+};
+
+struct _WapiHandleOps _wapi_namedevent_ops = {
+ NULL, /* close */
+ namedevent_signal, /* signal */
+ namedevent_own, /* own */
+ NULL, /* is_owned */
+};
+
+static gboolean event_pulse (gpointer handle);
+static gboolean event_reset (gpointer handle);
+static gboolean event_set (gpointer handle);
+
+static gboolean namedevent_pulse (gpointer handle);
+static gboolean namedevent_reset (gpointer handle);
+static gboolean namedevent_set (gpointer handle);
+
+static struct
+{
+ gboolean (*pulse)(gpointer handle);
+ gboolean (*reset)(gpointer handle);
+ gboolean (*set)(gpointer handle);
+} event_ops[WAPI_HANDLE_COUNT] = {
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {event_pulse, event_reset, event_set},
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {NULL},
+ {namedevent_pulse, namedevent_reset, namedevent_set},
};
-static pthread_once_t event_ops_once=PTHREAD_ONCE_INIT;
+void _wapi_event_details (gpointer handle_info)
+{
+ struct _WapiHandle_event *event = (struct _WapiHandle_event *)handle_info;
+
+ g_print ("manual: %s", event->manual?"TRUE":"FALSE");
+}
+
+static mono_once_t event_ops_once=MONO_ONCE_INIT;
static void event_ops_init (void)
{
_wapi_handle_register_capabilities (WAPI_HANDLE_EVENT,
WAPI_HANDLE_CAP_WAIT |
WAPI_HANDLE_CAP_SIGNAL);
+ _wapi_handle_register_capabilities (WAPI_HANDLE_NAMEDEVENT,
+ WAPI_HANDLE_CAP_WAIT |
+ WAPI_HANDLE_CAP_SIGNAL);
}
-static void event_close_shared(gpointer handle)
+static void event_signal(gpointer handle)
+{
+ SetEvent(handle);
+}
+
+static gboolean event_own (gpointer handle)
{
struct _WapiHandle_event *event_handle;
gboolean ok;
ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
+ (gpointer *)&event_handle);
if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
- return;
+ g_warning ("%s: error looking up event handle %p", __func__,
+ handle);
+ return (FALSE);
}
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": closing event handle %p", handle);
+ g_message("%s: owning event handle %p", __func__, handle);
#endif
+
+ if(event_handle->manual==FALSE) {
+ g_assert (event_handle->set_count > 0);
+
+ if (--event_handle->set_count == 0) {
+ _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+ }
+ }
+
+ return(TRUE);
}
-static void event_signal(gpointer handle)
+static void namedevent_signal (gpointer handle)
{
- ResetEvent(handle);
+ SetEvent (handle);
}
-static void event_own (gpointer handle)
+/* NB, always called with the shared handle lock held */
+static gboolean namedevent_own (gpointer handle)
{
- struct _WapiHandle_event *event_handle;
+ struct _WapiHandle_namedevent *namedevent_handle;
gboolean ok;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
- return;
+#ifdef DEBUG
+ g_message ("%s: owning named event handle %p", __func__, handle);
+#endif
+
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
+ (gpointer *)&namedevent_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up named event handle %p",
+ __func__, handle);
+ return(FALSE);
+ }
+
+ if (namedevent_handle->manual == FALSE) {
+ g_assert (namedevent_handle->set_count > 0);
+
+ if (--namedevent_handle->set_count == 0) {
+ _wapi_shared_handle_set_signal_state (handle, FALSE);
+ }
}
+ return (TRUE);
+}
+static gpointer event_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
+ gboolean manual, gboolean initial)
+{
+ struct _WapiHandle_event event_handle = {0};
+ gpointer handle;
+ int thr_ret;
+
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if an event
+ * was freshly created
+ */
+ SetLastError (ERROR_SUCCESS);
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": owning event handle %p", handle);
+ g_message ("%s: Creating unnamed event", __func__);
#endif
+
+ event_handle.manual = manual;
+ event_handle.set_count = 0;
- if(event_handle->manual==FALSE) {
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+ if (initial == TRUE) {
+ if (manual == FALSE) {
+ event_handle.set_count = 1;
+ }
}
+
+ handle = _wapi_handle_new (WAPI_HANDLE_EVENT, &event_handle);
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating event handle", __func__);
+ SetLastError (ERROR_GEN_FAILURE);
+ return(NULL);
+ }
+
+ pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+ handle);
+ thr_ret = _wapi_handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ if (initial == TRUE) {
+ _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ }
+
+#ifdef DEBUG
+ g_message("%s: created new event handle %p", __func__, handle);
+#endif
+
+ thr_ret = _wapi_handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ pthread_cleanup_pop (0);
+
+ return(handle);
}
+static gpointer namedevent_create (WapiSecurityAttributes *security G_GNUC_UNUSED,
+ gboolean manual, gboolean initial,
+ const gunichar2 *name G_GNUC_UNUSED)
+{
+ struct _WapiHandle_namedevent namedevent_handle = {{{0}}, 0};
+ gpointer handle;
+ gchar *utf8_name;
+ int thr_ret;
+ gpointer ret = NULL;
+ guint32 namelen;
+ gint32 offset;
+
+ /* w32 seems to guarantee that opening named objects can't
+ * race each other
+ */
+ thr_ret = _wapi_namespace_lock ();
+ g_assert (thr_ret == 0);
+
+ /* Need to blow away any old errors here, because code tests
+ * for ERROR_ALREADY_EXISTS on success (!) to see if an event
+ * was freshly created
+ */
+ SetLastError (ERROR_SUCCESS);
+
+ utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
+
+#ifdef DEBUG
+ g_message ("%s: Creating named event [%s]", __func__, utf8_name);
+#endif
+
+ offset = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
+ utf8_name);
+ if (offset == -1) {
+ /* The name has already been used for a different
+ * object.
+ */
+ SetLastError (ERROR_INVALID_HANDLE);
+ goto cleanup;
+ } else if (offset != 0) {
+ /* Not an error, but this is how the caller is
+ * informed that the event wasn't freshly created
+ */
+ SetLastError (ERROR_ALREADY_EXISTS);
+ }
+ /* Fall through to create the event handle. */
+
+ if (offset == 0) {
+ /* A new named event, so create both the private and
+ * shared parts
+ */
+
+ if (strlen (utf8_name) < MAX_PATH) {
+ namelen = strlen (utf8_name);
+ } else {
+ namelen = MAX_PATH;
+ }
+
+ memcpy (&namedevent_handle.sharedns.name, utf8_name, namelen);
+
+ namedevent_handle.manual = manual;
+ namedevent_handle.set_count = 0;
+
+ if (initial == TRUE) {
+ if (manual == FALSE) {
+ namedevent_handle.set_count = 1;
+ }
+ }
+
+ handle = _wapi_handle_new (WAPI_HANDLE_NAMEDEVENT,
+ &namedevent_handle);
+ } else {
+ /* A new reference to an existing named event, so just
+ * create the private part
+ */
+ handle = _wapi_handle_new_from_offset (WAPI_HANDLE_NAMEDEVENT,
+ offset, TRUE);
+ }
+
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error creating event handle", __func__);
+ SetLastError (ERROR_GEN_FAILURE);
+ goto cleanup;
+ }
+ ret = handle;
+
+ if (offset == 0) {
+ /* Set the initial state, as this is a completely new
+ * handle
+ */
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
+ if (initial == TRUE) {
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ }
+
+ _wapi_handle_unlock_shared_handles ();
+ }
+
+#ifdef DEBUG
+ g_message ("%s: returning event handle %p", __func__, handle);
+#endif
+
+cleanup:
+ g_free (utf8_name);
+
+ _wapi_namespace_unlock (NULL);
+
+ return(ret);
+
+}
+
+
/**
* CreateEvent:
* @security: Ignored for now.
*
* Return value: A new handle, or %NULL on error.
*/
-gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED, gboolean manual,
- gboolean initial, const guchar *name G_GNUC_UNUSED)
+gpointer CreateEvent(WapiSecurityAttributes *security G_GNUC_UNUSED,
+ gboolean manual, gboolean initial,
+ const gunichar2 *name G_GNUC_UNUSED)
+{
+ mono_once (&event_ops_once, event_ops_init);
+
+ if (name == NULL) {
+ return(event_create (security, manual, initial));
+ } else {
+ return(namedevent_create (security, manual, initial, name));
+ }
+}
+
+static gboolean event_pulse (gpointer handle)
{
struct _WapiHandle_event *event_handle;
- gpointer handle;
gboolean ok;
+ int thr_ret;
+
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
+ (gpointer *)&event_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up event handle %p", __func__,
+ handle);
+ return(FALSE);
+ }
- pthread_once (&event_ops_once, event_ops_init);
+ pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+ handle);
+ thr_ret = _wapi_handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
- handle=_wapi_handle_new (WAPI_HANDLE_EVENT);
- if(handle==_WAPI_HANDLE_INVALID) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error creating event handle");
- return(NULL);
+#ifdef DEBUG
+ g_message ("%s: Pulsing event handle %p", __func__, handle);
+#endif
+
+ if (event_handle->manual == TRUE) {
+ _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ } else {
+ event_handle->set_count = 1;
+ _wapi_handle_set_signal_state (handle, TRUE, FALSE);
}
+
+ thr_ret = _wapi_handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
- _wapi_handle_lock_handle (handle);
+ pthread_cleanup_pop (0);
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
- _wapi_handle_unlock_handle (handle);
- return(NULL);
+ if (event_handle->manual == TRUE) {
+ /* For a manual-reset event, we're about to try and
+ * get the handle lock again, so give other threads a
+ * chance
+ */
+ sched_yield ();
+
+ /* Reset the handle signal state */
+ /* I'm not sure whether or not we need a barrier here
+ * to make sure that all threads waiting on the event
+ * have proceeded. Currently we rely on broadcasting
+ * a condition.
+ */
+#ifdef DEBUG
+ g_message ("%s: Obtained write lock on event handle %p",
+ __func__, handle);
+#endif
+
+ pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle, handle);
+ thr_ret = _wapi_handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+
+ thr_ret = _wapi_handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+ pthread_cleanup_pop (0);
}
-
- event_handle->manual=manual;
- if(initial==TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ return(TRUE);
+}
+
+static gboolean namedevent_pulse (gpointer handle)
+{
+ struct _WapiHandle_namedevent *namedevent_handle;
+ gboolean ok;
+ int thr_ret;
+
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
+ (gpointer *)&namedevent_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up named event handle %p",
+ __func__, handle);
+ return(FALSE);
}
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": created new event handle %p",
- handle);
+ g_message ("%s: Pulsing named event handle %p", __func__, handle);
#endif
- _wapi_handle_unlock_handle (handle);
+ if (namedevent_handle->manual == TRUE) {
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ } else {
+ namedevent_handle->set_count = 1;
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ }
+
+ _wapi_handle_unlock_shared_handles ();
- return(handle);
+ if (namedevent_handle->manual == TRUE) {
+ /* For a manual-reset event, we're about to try and
+ * get the handle lock again, so give other processes
+ * a chance
+ */
+ _wapi_handle_spin (200);
+
+ /* Reset the handle signal state */
+ /* I'm not sure whether or not we need a barrier here
+ * to make sure that all threads waiting on the event
+ * have proceeded. Currently we rely on waiting for
+ * twice the shared handle poll interval.
+ */
+#ifdef DEBUG
+ g_message ("%s: Obtained write lock on event handle %p",
+ __func__, handle);
+#endif
+
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
+ _wapi_shared_handle_set_signal_state (handle, FALSE);
+
+ _wapi_handle_unlock_shared_handles ();
+ }
+
+ return(TRUE);
}
/**
* ever returns %TRUE).
*/
gboolean PulseEvent(gpointer handle)
+{
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
+
+ if (event_ops[type].pulse == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ return(event_ops[type].pulse (handle));
+}
+
+static gboolean event_reset (gpointer handle)
{
struct _WapiHandle_event *event_handle;
gboolean ok;
+ int thr_ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
+ (gpointer *)&event_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up event handle %p",
+ __func__, handle);
return(FALSE);
}
-
- _wapi_handle_lock_handle (handle);
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Pulsing event handle %p", handle);
+ g_message ("%s: Resetting event handle %p", __func__, handle);
#endif
- if(event_handle->manual==TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+ handle);
+ thr_ret = _wapi_handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ if (_wapi_handle_issignalled (handle) == FALSE) {
+#ifdef DEBUG
+ g_message ("%s: No need to reset event handle %p", __func__,
+ handle);
+#endif
} else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+#ifdef DEBUG
+ g_message ("%s: Obtained write lock on event handle %p",
+ __func__, handle);
+#endif
+
+ _wapi_handle_set_signal_state (handle, FALSE, FALSE);
}
+
+ event_handle->set_count = 0;
+
+ thr_ret = _wapi_handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(TRUE);
+}
- _wapi_handle_unlock_handle (handle);
+static gboolean namedevent_reset (gpointer handle)
+{
+ struct _WapiHandle_namedevent *namedevent_handle;
+ gboolean ok;
+ int thr_ret;
- if(event_handle->manual==TRUE) {
- /* For a manual-reset event, we're about to try and
- * get the handle lock again, so give other threads a
- * chance
- */
- sched_yield ();
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
+ (gpointer *)&namedevent_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up named event handle %p",
+ __func__, handle);
+ return(FALSE);
+ }
- /* Reset the handle signal state */
- /* I'm not sure whether or not we need a barrier here
- * to make sure that all threads waiting on the event
- * have proceeded. Currently we rely on broadcasting
- * a condition.
- */
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": Obtained write lock on event handle %p", handle);
+ g_message ("%s: Resetting named event handle %p", __func__, handle);
#endif
- _wapi_handle_lock_handle (handle);
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
- _wapi_handle_unlock_handle (handle);
- }
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
+ if (_wapi_handle_issignalled (handle) == FALSE) {
+#ifdef DEBUG
+ g_message ("%s: No need to reset named event handle %p",
+ __func__, handle);
+#endif
+ } else {
+#ifdef DEBUG
+ g_message ("%s: Obtained write lock on named event handle %p",
+ __func__, handle);
+#endif
+ _wapi_shared_handle_set_signal_state (handle, FALSE);
+ }
+
+ namedevent_handle->set_count = 0;
+
+ _wapi_handle_unlock_shared_handles ();
+
return(TRUE);
}
* ever returns %TRUE).
*/
gboolean ResetEvent(gpointer handle)
+{
+ WapiHandleType type;
+
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ type = _wapi_handle_type (handle);
+
+ if (event_ops[type].reset == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ return(event_ops[type].reset (handle));
+}
+
+static gboolean event_set (gpointer handle)
{
struct _WapiHandle_event *event_handle;
gboolean ok;
+ int thr_ret;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
+ (gpointer *)&event_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up event handle %p", __func__,
+ handle);
return(FALSE);
}
+
+ pthread_cleanup_push ((void(*)(void *))_wapi_handle_unlock_handle,
+ handle);
+ thr_ret = _wapi_handle_lock_handle (handle);
+ g_assert (thr_ret == 0);
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Resetting event handle %p",
- handle);
+ g_message ("%s: Setting event handle %p", __func__, handle);
#endif
- _wapi_handle_lock_handle (handle);
- if(_wapi_handle_issignalled (handle)==FALSE) {
+ if (event_handle->manual == TRUE) {
+ _wapi_handle_set_signal_state (handle, TRUE, TRUE);
+ } else {
+ event_handle->set_count = 1;
+ _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ }
-#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": No need to reset event handle %p", handle);
-#endif
+ thr_ret = _wapi_handle_unlock_handle (handle);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(TRUE);
+}
- _wapi_handle_unlock_handle (handle);
- return(TRUE);
+static gboolean namedevent_set (gpointer handle)
+{
+ struct _WapiHandle_namedevent *namedevent_handle;
+ gboolean ok;
+ int thr_ret;
+
+ ok = _wapi_lookup_handle (handle, WAPI_HANDLE_NAMEDEVENT,
+ (gpointer *)&namedevent_handle);
+ if (ok == FALSE) {
+ g_warning ("%s: error looking up named event handle %p",
+ __func__, handle);
+ return(FALSE);
}
+ thr_ret = _wapi_handle_lock_shared_handles ();
+ g_assert (thr_ret == 0);
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION
- ": Obtained write lock on event handle %p", handle);
+ g_message ("%s: Setting named event handle %p", __func__, handle);
#endif
- _wapi_handle_set_signal_state (handle, FALSE, FALSE);
+ if (namedevent_handle->manual == TRUE) {
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ } else {
+ namedevent_handle->set_count = 1;
+ _wapi_shared_handle_set_signal_state (handle, TRUE);
+ }
+
+ _wapi_handle_unlock_shared_handles ();
- _wapi_handle_unlock_handle (handle);
-
return(TRUE);
}
*/
gboolean SetEvent(gpointer handle)
{
- struct _WapiHandle_event *event_handle;
- gboolean ok;
+ WapiHandleType type;
- ok=_wapi_lookup_handle (handle, WAPI_HANDLE_EVENT,
- (gpointer *)&event_handle, NULL);
- if(ok==FALSE) {
- g_warning (G_GNUC_PRETTY_FUNCTION
- ": error looking up event handle %p", handle);
+ if (handle == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
return(FALSE);
}
- _wapi_handle_lock_handle (handle);
+ type = _wapi_handle_type (handle);
+
+ if (event_ops[type].set == NULL) {
+ SetLastError (ERROR_INVALID_HANDLE);
+ return(FALSE);
+ }
+
+ return(event_ops[type].set (handle));
+}
+
+gpointer OpenEvent (guint32 access G_GNUC_UNUSED, gboolean inherit G_GNUC_UNUSED, const gunichar2 *name)
+{
+ gpointer handle;
+ gchar *utf8_name;
+ int thr_ret;
+ gpointer ret = NULL;
+ gint32 offset;
+
+ mono_once (&event_ops_once, event_ops_init);
+
+ /* w32 seems to guarantee that opening named objects can't
+ * race each other
+ */
+ thr_ret = _wapi_namespace_lock ();
+ g_assert (thr_ret == 0);
+ utf8_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
+
#ifdef DEBUG
- g_message(G_GNUC_PRETTY_FUNCTION ": Setting event handle %p", handle);
+ g_message ("%s: Opening named event [%s]", __func__, utf8_name);
#endif
+
+ offset = _wapi_search_handle_namespace (WAPI_HANDLE_NAMEDEVENT,
+ utf8_name);
+ if (offset == -1) {
+ /* The name has already been used for a different
+ * object.
+ */
+ SetLastError (ERROR_INVALID_HANDLE);
+ goto cleanup;
+ } else if (offset == 0) {
+ /* This name doesn't exist */
+ SetLastError (ERROR_FILE_NOT_FOUND); /* yes, really */
+ goto cleanup;
+ }
- if(event_handle->manual==TRUE) {
- _wapi_handle_set_signal_state (handle, TRUE, TRUE);
- } else {
- _wapi_handle_set_signal_state (handle, TRUE, FALSE);
+ /* A new reference to an existing named event, so just create
+ * the private part
+ */
+ handle = _wapi_handle_new_from_offset (WAPI_HANDLE_NAMEDEVENT, offset,
+ TRUE);
+
+ if (handle == _WAPI_HANDLE_INVALID) {
+ g_warning ("%s: error opening named event handle", __func__);
+ SetLastError (ERROR_GEN_FAILURE);
+ goto cleanup;
}
+ ret = handle;
- _wapi_handle_unlock_handle (handle);
+#ifdef DEBUG
+ g_message ("%s: returning named event handle %p", __func__, handle);
+#endif
- return(TRUE);
-}
+cleanup:
+ g_free (utf8_name);
+
+ _wapi_namespace_unlock (NULL);
+
+ return(ret);
+}