[runtime] Use coop handles for ves_icall_System_Threading_Events_OpenEvent_internal
authorAleksey Kliger <aleksey@xamarin.com>
Fri, 26 May 2017 14:01:10 +0000 (10:01 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Fri, 26 May 2017 18:26:19 +0000 (14:26 -0400)
mono/metadata/icall-def.h
mono/metadata/w32event-unix.c
mono/metadata/w32event-win32.c
mono/metadata/w32event.h

index 6657624616e88248fb2738e2b142c5ea2cf4399e..d9d7f851714715c628c97ffe7b7952222c22ef1f 100644 (file)
@@ -919,7 +919,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)
 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)
+HANDLES(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)
 
index 50beb4b72b020216597b4f99f5f63745f0251245..d99023e9e34da6ffa0f8ff58ff6d50d423e1796b 100644 (file)
@@ -23,6 +23,8 @@
 static gpointer
 mono_w32event_create_full (MonoBoolean manual, MonoBoolean initial, const gchar *name, gint32 *err);
 
+static gpointer
+mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *error);
 
 typedef struct {
        gboolean manual;
@@ -386,18 +388,25 @@ ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle)
 }
 
 gpointer
-ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights G_GNUC_UNUSED, gint32 *error)
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoStringHandle name, gint32 rights G_GNUC_UNUSED, gint32 *err, MonoError *error)
 {
-       gpointer handle;
-       gchar *utf8_name;
+       error_init (error);
+       gchar *utf8_name = mono_string_handle_to_utf8 (name, error);
+       return_val_if_nok (error, NULL);
+       gpointer handle = mono_w32event_open (utf8_name, rights, err);
+       g_free (utf8_name);
+       return handle;
+}
 
+gpointer
+mono_w32event_open (const gchar *utf8_name, gint32 rights G_GNUC_UNUSED, gint32 *error)
+{
+       gpointer handle;
        *error = ERROR_SUCCESS;
 
        /* w32 seems to guarantee that opening named objects can't race each other */
        mono_w32handle_namespace_lock ();
 
-       utf8_name = g_utf16_to_utf8 (mono_string_chars (name), -1, NULL, NULL, NULL);
-
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Opening named event [%s]", __func__, utf8_name);
 
        handle = mono_w32handle_namespace_search_handle (MONO_W32HANDLE_NAMEDEVENT, utf8_name);
@@ -414,8 +423,6 @@ ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 r
        mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: returning named event handle %p", __func__, handle);
 
 cleanup:
-       g_free (utf8_name);
-
        mono_w32handle_namespace_unlock ();
 
        return handle;
index c0c9df3e71b81fac213f254a973e7d0a48979f88..9894053b617e4b08474bd2180fb06c06efc05da1 100644 (file)
@@ -84,15 +84,28 @@ ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle)
 }
 
 gpointer
-ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error)
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoStringHandle name, gint32 rights, gint32 *err, MonoError *error)
 {
        gpointer handle;
 
-       *error = ERROR_SUCCESS;
+       error_init (error);
+
+       *err = ERROR_SUCCESS;
 
-       handle = OpenEvent (rights, FALSE, mono_string_chars (name));
+       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;
+       handle = OpenEvent (rights, FALSE, uniname);
        if (!handle)
-               *error = GetLastError ();
+               *err = GetLastError ();
+       MONO_EXIT_GC_SAFE;
+
+       if (gchandle)
+               mono_gchandle_free (gchandle);
 
        return handle;
 }
index f9847d8b1972583ef7b3e1ff104b68aba7095be2..779407de845ae746dea928826b30cc4bb24085c7 100644 (file)
@@ -40,7 +40,7 @@ void
 ves_icall_System_Threading_Events_CloseEvent_internal (gpointer handle);
 
 gpointer
-ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error);
+ves_icall_System_Threading_Events_OpenEvent_internal (MonoStringHandle name, gint32 rights, gint32 *err, MonoError *error);
 
 typedef struct MonoW32HandleNamedEvent MonoW32HandleNamedEvent;