* Remove unused named handle support.
* Remove more unused code.
handle.c
handle.h
w32event.h
- w32handle-namespace.h
- w32handle-namespace.c
w32handle.h
w32handle.c
w32error.h
#ifndef HOST_WIN32
mono_w32handle_init ();
- mono_w32handle_namespace_init ();
#endif
mono_w32event_init ();
#include "w32event.h"
#include "w32error.h"
-#include "w32handle-namespace.h"
#include "mono/utils/mono-error-internals.h"
#include "mono/utils/mono-logger-internals.h"
#include "mono/metadata/handle.h"
#define MAX_PATH 260
-static gpointer
-mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const char *name, gsize name_length, gint32 *win32error);
-
-static gpointer
-mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *error);
-
typedef struct {
gboolean manual;
guint32 set_count;
} MonoW32HandleEvent;
-struct MonoW32HandleNamedEvent {
- MonoW32HandleEvent e;
- MonoW32HandleNamespace sharedns;
-};
+static gpointer event_create (gboolean manual, gboolean initial);
static gint32 event_handle_signal (MonoW32Handle *handle_data)
{
event->manual ? "TRUE" : "FALSE", event->set_count);
}
-static void namedevent_details (MonoW32Handle *handle_data)
-{
- MonoW32HandleNamedEvent *namedevent = (MonoW32HandleNamedEvent *)handle_data->specific;
- g_print ("manual: %s, set_count: %d, name: \"%s\"",
- namedevent->e.manual ? "TRUE" : "FALSE", namedevent->e.set_count, namedevent->sharedns.name);
-}
-
static const gchar* event_typename (void)
{
return "Event";
return sizeof (MonoW32HandleEvent);
}
-static const gchar* namedevent_typename (void)
-{
- return "N.Event";
-}
-
-static gsize namedevent_typesize (void)
-{
- return sizeof (MonoW32HandleNamedEvent);
-}
-
void
mono_w32event_init (void)
{
event_typesize, /* typesize */
};
- static const MonoW32HandleOps namedevent_ops = {
- NULL, /* close */
- event_handle_signal, /* signal */
- event_handle_own, /* own */
- NULL, /* is_owned */
- NULL, /* special_wait */
- NULL, /* prewait */
- namedevent_details, /* details */
- namedevent_typename, /* typename */
- namedevent_typesize, /* typesize */
- };
-
mono_w32handle_register_ops (MONO_W32TYPE_EVENT, &event_ops);
- mono_w32handle_register_ops (MONO_W32TYPE_NAMEDEVENT, &namedevent_ops);
mono_w32handle_register_capabilities (MONO_W32TYPE_EVENT,
(MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
- mono_w32handle_register_capabilities (MONO_W32TYPE_NAMEDEVENT,
- (MonoW32HandleCapability)(MONO_W32HANDLE_CAP_WAIT | MONO_W32HANDLE_CAP_SIGNAL));
}
gpointer
mono_w32event_create (gboolean manual, gboolean initial)
{
- gint32 win32error = ERROR_SUCCESS;
+ /* 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 */
+ mono_w32error_set_last (ERROR_SUCCESS);
- gpointer handle = mono_w32event_create_full (manual, initial, NULL, 0, &win32error);
+ gpointer handle = event_create (manual, initial);
+
+ gint32 win32error = mono_w32error_get_last ();
g_assert ((win32error != ERROR_SUCCESS) == !handle);
return handle;
+
}
gboolean
return mono_w32handle_close (handle);
}
-void
-mono_w32event_set (gpointer handle)
-{
- ves_icall_System_Threading_Events_SetEvent_internal (handle);
-}
-
static gpointer event_handle_create (MonoW32HandleEvent *event_handle, MonoW32Type type, gboolean manual, gboolean initial)
{
MonoW32Handle *handle_data;
return event_handle_create (&event_handle, MONO_W32TYPE_EVENT, manual, initial);
}
-static gpointer
-namedevent_create (gboolean manual, gboolean initial, const char *utf8_name, gsize utf8_len)
-{
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: creating %s handle",
- __func__, mono_w32handle_get_typename (MONO_W32TYPE_NAMEDEVENT));
-
- // Opening named objects does not race.
- mono_w32handle_namespace_lock ();
-
- gpointer handle = mono_w32handle_namespace_search_handle (MONO_W32TYPE_NAMEDEVENT, utf8_name);
-
- if (handle == INVALID_HANDLE_VALUE) {
- /* The name has already been used for a different object. */
- handle = NULL;
- mono_w32error_set_last (ERROR_INVALID_HANDLE);
- } else if (handle) {
- /* Not an error, but this is how the caller is informed that the event wasn't freshly created */
- mono_w32error_set_last (ERROR_ALREADY_EXISTS);
-
- /* mono_w32handle_namespace_search_handle already adds a ref to the handle */
- } else {
- /* A new named event */
- MonoW32HandleNamedEvent namedevent_handle;
-
- // FIXME Silent truncation.
-
- size_t len = utf8_len < MAX_PATH ? utf8_len : MAX_PATH;
- memcpy (&namedevent_handle.sharedns.name [0], utf8_name, len);
- namedevent_handle.sharedns.name [len] = '\0';
-
- handle = event_handle_create ((MonoW32HandleEvent*) &namedevent_handle, MONO_W32TYPE_NAMEDEVENT, manual, initial);
- }
-
- mono_w32handle_namespace_unlock ();
-
- return handle;
-}
-
-gpointer
-mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const char *name, gsize name_length, gint32 *win32error)
-{
- /* 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 */
- mono_w32error_set_last (ERROR_SUCCESS);
-
- gpointer event = name ? namedevent_create (manual, initial, name, name_length) : event_create (manual, initial);
-
- *win32error = mono_w32error_get_last ();
-
- return event;
-}
-
-gboolean
-ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle)
+void
+mono_w32event_set (gpointer handle)
{
MonoW32Handle *handle_data;
MonoW32HandleEvent *event_handle;
if (!mono_w32handle_lookup_and_ref (handle, &handle_data)) {
g_warning ("%s: unkown handle %p", __func__, handle);
mono_w32error_set_last (ERROR_INVALID_HANDLE);
- return FALSE;
+ return;
}
- if (handle_data->type != MONO_W32TYPE_EVENT && handle_data->type != MONO_W32TYPE_NAMEDEVENT) {
+ if (handle_data->type != MONO_W32TYPE_EVENT) {
g_warning ("%s: unkown event handle %p", __func__, handle);
mono_w32error_set_last (ERROR_INVALID_HANDLE);
mono_w32handle_unref (handle_data);
- return FALSE;
+ return;
}
event_handle = (MonoW32HandleEvent*) handle_data->specific;
mono_w32handle_unlock (handle_data);
mono_w32handle_unref (handle_data);
- return TRUE;
-}
-
-gpointer
-mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *win32error)
-{
- *win32error = ERROR_SUCCESS;
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: Opening named event [%s]", __func__, utf8_name);
-
- // Opening named objects does not race.
- mono_w32handle_namespace_lock ();
-
- gpointer handle = mono_w32handle_namespace_search_handle (MONO_W32TYPE_NAMEDEVENT, utf8_name);
-
- mono_w32handle_namespace_unlock ();
-
- if (handle == INVALID_HANDLE_VALUE) {
- /* The name has already been used for a different object. */
- *win32error = ERROR_INVALID_HANDLE;
- return handle;
- } else if (!handle) {
- /* This name doesn't exist */
- *win32error = ERROR_FILE_NOT_FOUND;
- return handle;
- }
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_EVENT, "%s: returning named event handle %p", __func__, handle);
-
- return handle;
-}
-
-MonoW32HandleNamespace*
-mono_w32event_get_namespace (MonoW32HandleNamedEvent *event)
-{
- return &event->sharedns;
}
#include "object.h"
#include "object-internals.h"
-#include "w32handle-namespace.h"
+#include "w32handle.h"
#include <mono/metadata/icalls.h>
void
void
mono_w32event_set (gpointer handle);
-ICALL_EXPORT
-gboolean
-ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle);
-
-typedef struct MonoW32HandleNamedEvent MonoW32HandleNamedEvent;
-
-MonoW32HandleNamespace*
-mono_w32event_get_namespace (MonoW32HandleNamedEvent *event);
-
#endif /* _MONO_METADATA_W32EVENT_H_ */
+++ /dev/null
-/**
- * \file
- * namespace for w32handles
- *
- * Author:
- * Ludovic Henry (luhenry@microsoft.com)
- *
- * Licensed under the MIT license. See LICENSE file in the project root for full license information.
- */
-
-#include <config.h>
-
-#ifndef HOST_WIN32
-
-#include "w32handle-namespace.h"
-
-#include "w32event.h"
-#include "mono/utils/mono-logger-internals.h"
-#include "mono/utils/mono-coop-mutex.h"
-
-static MonoCoopMutex lock;
-
-void
-mono_w32handle_namespace_init (void)
-{
- mono_coop_mutex_init (&lock);
-}
-
-void
-mono_w32handle_namespace_lock (void)
-{
- mono_coop_mutex_lock (&lock);
-}
-
-void
-mono_w32handle_namespace_unlock (void)
-{
- mono_coop_mutex_unlock (&lock);
-}
-
-static gboolean
-has_namespace (MonoW32Type type)
-{
- switch (type) {
- case MONO_W32TYPE_NAMEDEVENT:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-typedef struct {
- gpointer ret;
- MonoW32Type type;
- const gchar *name;
-} NamespaceSearchHandleData;
-
-static gboolean
-mono_w32handle_namespace_search_handle_callback (MonoW32Handle *handle_data, gpointer user_data)
-{
- NamespaceSearchHandleData *search_data;
- MonoW32HandleNamespace *sharedns;
-
- if (!has_namespace (handle_data->type))
- return FALSE;
-
- search_data = (NamespaceSearchHandleData*) user_data;
-
- switch (handle_data->type) {
- case MONO_W32TYPE_NAMEDEVENT: sharedns = mono_w32event_get_namespace ((MonoW32HandleNamedEvent*) handle_data->specific); break;
- default:
- g_assert_not_reached ();
- }
-
- if (strcmp (sharedns->name, search_data->name) == 0) {
- if (handle_data->type != search_data->type) {
- /* Its the wrong type, so fail now */
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_HANDLE, "%s: handle %p matches name but is wrong type: %s",
- __func__, handle_data, mono_w32handle_get_typename (handle_data->type));
- search_data->ret = INVALID_HANDLE_VALUE;
- } else {
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_HANDLE, "%s: handle %p matches name and type",
- __func__, handle_data);
-
- /* we do not want the handle to be destroyed before we return it */
- search_data->ret = mono_w32handle_duplicate (handle_data);
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-gpointer
-mono_w32handle_namespace_search_handle (MonoW32Type type, const gchar *name)
-{
- NamespaceSearchHandleData search_data;
-
- if (!has_namespace (type))
- g_error ("%s: type %s does not have a namespace", __func__, mono_w32handle_get_typename (type));
-
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_HANDLE, "%s: Lookup for handle named [%s] type %s",
- __func__, name, mono_w32handle_get_typename (type));
-
- search_data.ret = NULL;
- search_data.type = type;
- search_data.name = name;
- mono_w32handle_foreach (mono_w32handle_namespace_search_handle_callback, &search_data);
- return search_data.ret;
-}
-
-#endif
+++ /dev/null
-/**
- * \file
- */
-
-#ifndef _MONO_METADATA_W32HANDLE_NAMESPACE_H_
-#define _MONO_METADATA_W32HANDLE_NAMESPACE_H_
-
-#include <config.h>
-#include <glib.h>
-
-#include "mono/metadata/w32handle.h"
-
-#define MONO_W32HANDLE_NAMESPACE_MAX_PATH 260
-
-typedef struct {
- gchar name [MONO_W32HANDLE_NAMESPACE_MAX_PATH + 1];
-} MonoW32HandleNamespace;
-
-void
-mono_w32handle_namespace_init (void);
-
-void
-mono_w32handle_namespace_lock (void);
-
-void
-mono_w32handle_namespace_unlock (void);
-
-gpointer
-mono_w32handle_namespace_search_handle (MonoW32Type type, const gchar *name);
-
-#endif /* _MONO_METADATA_W32HANDLE_NAMESPACE_H_ */
return TRUE;
}
-void
-mono_w32handle_foreach (gboolean (*on_each)(MonoW32Handle *handle_data, gpointer user_data), gpointer user_data)
-{
- MonoW32HandleSlot *slot;
- GPtrArray *handles_to_destroy;
- guint32 i;
-
- handles_to_destroy = NULL;
-
- mono_coop_mutex_lock (&scan_mutex);
-
- for (slot = handles_slots_first; slot; slot = slot->next) {
- for (i = 0; i < HANDLES_PER_SLOT; i++) {
- MonoW32Handle *handle_data;
- gboolean destroy, finished;
-
- handle_data = &slot->handles [i];
- if (handle_data->type == MONO_W32TYPE_UNUSED)
- continue;
-
- if (!mono_w32handle_ref_core (handle_data)) {
- /* we are racing with mono_w32handle_unref:
- * the handle ref has been decremented, but it
- * hasn't yet been destroyed. */
- continue;
- }
-
- finished = on_each (handle_data, user_data);
-
- /* we might have to destroy the handle here, as
- * it could have been unrefed in another thread */
- destroy = mono_w32handle_unref_core (handle_data);
- if (destroy) {
- /* we do not destroy it while holding the scan_mutex
- * lock, because w32handle_destroy also needs to take
- * the lock, and it calls user code which might lead
- * to a deadlock */
- if (!handles_to_destroy)
- handles_to_destroy = g_ptr_array_sized_new (4);
- g_ptr_array_add (handles_to_destroy, (gpointer) handle_data);
- }
-
- if (finished)
- goto done;
- }
- }
-
-done:
- mono_coop_mutex_unlock (&scan_mutex);
-
- if (handles_to_destroy) {
- for (i = 0; i < handles_to_destroy->len; ++i)
- w32handle_destroy ((MonoW32Handle*) handles_to_destroy->pdata [i]);
-
- g_ptr_array_free (handles_to_destroy, TRUE);
- }
-}
-
static gboolean
mono_w32handle_ref_core (MonoW32Handle *handle_data)
{
return ret;
}
#endif /* HOST_WIN32 */
-
-static MonoW32Handle*
-mono_w32handle_has_duplicates (MonoW32Handle *handles [ ], gsize nhandles)
-{
- if (nhandles < 2 || nhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
- return NULL;
-
- MonoW32Handle *sorted [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS]; // 64
- memcpy (sorted, handles, nhandles * sizeof (handles[0]));
- mono_qsort (sorted, nhandles, sizeof (sorted [0]), g_direct_equal);
- for (gsize i = 1; i < nhandles; ++i) {
- MonoW32Handle * const h1 = sorted [i - 1];
- MonoW32Handle * const h2 = sorted [i];
- if (h1 == h2)
- return h1;
- }
-
- return NULL;
-}
-
-static void
-mono_w32handle_clear_duplicates (MonoW32Handle *handles [ ], gsize nhandles)
-{
- for (gsize i = 0; i < nhandles; ++i) {
- if (!handles [i])
- continue;
- for (gsize j = i + 1; j < nhandles; ++j) {
- if (handles [i] == handles [j]) {
- mono_w32handle_unref (handles [j]);
- handles [j] = NULL;
- }
- }
- }
-}
-
-static void
-mono_w32handle_check_duplicates (MonoW32Handle *handles [ ], gsize nhandles, gboolean waitall, MonoError *error)
-{
- // Duplication is ok for WaitAny, exception for WaitAll.
- // System.DuplicateWaitObjectException: Duplicate objects in argument.
-
- MonoW32Handle *duplicate = mono_w32handle_has_duplicates (handles, nhandles);
- if (!duplicate)
- return;
-
- if (waitall) {
- mono_error_set_duplicate_wait_object (error);
- mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_HANDLE, "mono_w32handle_wait_multiple: handle %p is duplicated", duplicate);
- return;
- }
-
- // There is at least one duplicate. This is not an error.
- // Remove all duplicates -- in-place in order to return the
- // lowest signaled, equal to the caller's indices, and ease
- // the exit path's dereference.
- // That is, we cannot use sorted data, nor can we
- // compress the array to remove elements. We must operate
- // on each element in its original index, but we can skip some.
-
- mono_w32handle_clear_duplicates (handles, nhandles);
-}
typedef enum {
MONO_W32TYPE_UNUSED = 0,
MONO_W32TYPE_EVENT,
- MONO_W32TYPE_PROCESS,
- MONO_W32TYPE_NAMEDEVENT,
MONO_W32TYPE_COUNT
} MonoW32Type;
mono_w32handle_unref (MonoW32Handle *handle_data);
void
-mono_w32handle_foreach (gboolean (*on_each)(MonoW32Handle *handle_data, gpointer user_data), gpointer user_data);
-
-void
mono_w32handle_register_capabilities (MonoW32Type type, MonoW32HandleCapability caps);
void