From 0a3a12b9aac30a49366cd1ae90223be49b325711 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Thu, 25 May 2017 18:21:31 -0400 Subject: [PATCH] [w32event] Use coop handles for System.Threading.NativeEventCalls.CreateEvent_internal - Make a new mono_w32event_create_full on unix - Convert the MonoString to utf8 (unix) or utf16 (win32) in the icall, then call an implementation func. - transition to GC safe mode around the win32 api call on Windows --- mono/metadata/icall-def.h | 2 +- mono/metadata/w32event-unix.c | 32 +++++++++++++++++++++++--------- mono/metadata/w32event-win32.c | 19 +++++++++++++++---- mono/metadata/w32event.h | 3 ++- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 99d8537b253..6657624616e 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -918,7 +918,7 @@ ICALL(MUTEX_3, "ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex ICALL_TYPE(NATIVEC, "System.Threading.NativeEventCalls", NATIVEC_1) ICALL(NATIVEC_1, "CloseEvent_internal", ves_icall_System_Threading_Events_CloseEvent_internal) -ICALL(NATIVEC_2, "CreateEvent_internal(bool,bool,string,int&)", ves_icall_System_Threading_Events_CreateEvent_internal) +HANDLES(ICALL(NATIVEC_2, "CreateEvent_internal(bool,bool,string,int&)", ves_icall_System_Threading_Events_CreateEvent_internal)) ICALL(NATIVEC_3, "OpenEvent_internal(string,System.Security.AccessControl.EventWaitHandleRights,int&)", ves_icall_System_Threading_Events_OpenEvent_internal) ICALL(NATIVEC_4, "ResetEvent_internal", ves_icall_System_Threading_Events_ResetEvent_internal) ICALL(NATIVEC_5, "SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal) diff --git a/mono/metadata/w32event-unix.c b/mono/metadata/w32event-unix.c index 246ddadf3f7..50beb4b72b0 100644 --- a/mono/metadata/w32event-unix.c +++ b/mono/metadata/w32event-unix.c @@ -12,11 +12,18 @@ #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" +#include "mono/metadata/object-internals.h" #include "mono/metadata/w32handle.h" #define MAX_PATH 260 +static gpointer +mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const gchar *name, gint32 *err); + + typedef struct { gboolean manual; guint32 set_count; @@ -152,7 +159,7 @@ mono_w32event_create (gboolean manual, gboolean initial) gpointer handle; gint32 error; - handle = ves_icall_System_Threading_Events_CreateEvent_internal (manual, initial, NULL, &error); + handle = mono_w32event_create_full (manual, initial, NULL, &error); if (error != ERROR_SUCCESS) g_assert (!handle); @@ -213,10 +220,9 @@ static gpointer event_create (gboolean manual, gboolean initial) return event_handle_create (&event_handle, MONO_W32HANDLE_EVENT, manual, initial); } -static gpointer namedevent_create (gboolean manual, gboolean initial, const gunichar2 *name G_GNUC_UNUSED) +static gpointer namedevent_create (gboolean manual, gboolean initial, const gchar *utf8_name G_GNUC_UNUSED) { gpointer handle; - gchar *utf8_name; mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: creating %s handle", __func__, mono_w32handle_get_typename (MONO_W32HANDLE_NAMEDEVENT)); @@ -224,8 +230,7 @@ static gpointer namedevent_create (gboolean manual, gboolean initial, const guni /* w32 seems to guarantee that opening named objects can't race each other */ mono_w32handle_namespace_lock (); - glong utf8_len = 0; - utf8_name = g_utf16_to_utf8 (name, -1, NULL, &utf8_len, NULL); + glong utf8_len = strlen (utf8_name); handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDEVENT, utf8_name); if (handle == INVALID_HANDLE_VALUE) { @@ -248,15 +253,13 @@ static gpointer namedevent_create (gboolean manual, gboolean initial, const guni handle = event_handle_create ((MonoW32HandleEvent*) &namedevent_handle, MONO_W32HANDLE_NAMEDEVENT, manual, initial); } - g_free (utf8_name); - mono_w32handle_namespace_unlock (); return handle; } gpointer -ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error) +mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const gchar *name, gint32 *error) { gpointer event; @@ -265,13 +268,24 @@ ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, Mono * was freshly created */ mono_w32error_set_last (ERROR_SUCCESS); - event = name ? namedevent_create (manual, initial, mono_string_chars (name)) : event_create (manual, initial); + event = name ? namedevent_create (manual, initial, name) : event_create (manual, initial); *error = mono_w32error_get_last (); return event; } +gpointer +ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoStringHandle name, gint32 *err, MonoError *error) +{ + error_init (error); + gchar *utf8_name = mono_string_handle_to_utf8 (name, error); + return_val_if_nok (error, NULL); + gpointer result = mono_w32event_create_full (manual, initial, utf8_name, err); + g_free (utf8_name); + return result; +} + gboolean ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle) { diff --git a/mono/metadata/w32event-win32.c b/mono/metadata/w32event-win32.c index 792735b0268..c0c9df3e71b 100644 --- a/mono/metadata/w32event-win32.c +++ b/mono/metadata/w32event-win32.c @@ -12,6 +12,8 @@ #include #include +#include +#include void mono_w32event_init (void) @@ -43,13 +45,22 @@ mono_w32event_reset (gpointer handle) } gpointer -ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error) +ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoStringHandle name, gint32 *err, MonoError *error) { gpointer event; - event = CreateEvent (NULL, manual, initial, name ? mono_string_chars (name) : NULL); - - *error = GetLastError (); + error_init (error); + + uint32_t gchandle = 0; + gunichar2 *uniname = NULL; + if (!MONO_HANDLE_IS_NULL (name)) + uniname = mono_string_handle_pin_chars (name, &gchandle); + MONO_ENTER_GC_SAFE; + event = CreateEvent (NULL, manual, initial, uniname); + *err = GetLastError (); + MONO_EXIT_GC_SAFE; + if (gchandle) + mono_gchandle_free (gchandle); return event; } diff --git a/mono/metadata/w32event.h b/mono/metadata/w32event.h index 3e8d65de06e..f9847d8b197 100644 --- a/mono/metadata/w32event.h +++ b/mono/metadata/w32event.h @@ -9,6 +9,7 @@ #include #include "object.h" +#include "object-internals.h" #include "w32handle-namespace.h" void @@ -27,7 +28,7 @@ void mono_w32event_reset (gpointer handle); gpointer -ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, gint32 *error); +ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoStringHandle name, gint32 *err, MonoError *error); gboolean ves_icall_System_Threading_Events_SetEvent_internal (gpointer handle); -- 2.25.1