[runtime] Use coop handles for ves_icall_System_Threading_Mutex_CreateMutex_internal
authorAleksey Kliger <aleksey@xamarin.com>
Fri, 26 May 2017 15:08:22 +0000 (11:08 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Fri, 26 May 2017 18:26:21 +0000 (14:26 -0400)
mono/metadata/icall-def.h
mono/metadata/w32mutex-unix.c
mono/metadata/w32mutex-win32.c
mono/metadata/w32mutex.h

index d9d7f851714715c628c97ffe7b7952222c22ef1f..4efde18a7e163bd0ce19bbe640855c674ea9ba58 100644 (file)
@@ -912,7 +912,7 @@ ICALL(MONIT_7, "Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait)
 ICALL(MONIT_9, "try_enter_with_atomic_var", ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var)
 
 ICALL_TYPE(MUTEX, "System.Threading.Mutex", MUTEX_1)
-ICALL(MUTEX_1, "CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal)
+HANDLES(ICALL(MUTEX_1, "CreateMutex_internal(bool,string,bool&)", ves_icall_System_Threading_Mutex_CreateMutex_internal))
 ICALL(MUTEX_2, "OpenMutex_internal(string,System.Security.AccessControl.MutexRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Mutex_OpenMutex_internal)
 ICALL(MUTEX_3, "ReleaseMutex_internal(intptr)", ves_icall_System_Threading_Mutex_ReleaseMutex_internal)
 
index ee3ae7e740d24b3990dc2621f9f63fd536892252..6e3a5d4f4cd07b6caefc7b3d7c897da170f6c674 100644 (file)
@@ -304,10 +304,9 @@ static gpointer mutex_create (gboolean owned)
        return mutex_handle_create (&mutex_handle, MONO_W32HANDLE_MUTEX, owned);
 }
 
-static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
+static gpointer namedmutex_create (gboolean owned, const gchar *utf8_name)
 {
        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_NAMEDMUTEX));
@@ -315,8 +314,7 @@ static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
        /* 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_NAMEDMUTEX, utf8_name);
        if (handle == INVALID_HANDLE_VALUE) {
@@ -339,18 +337,17 @@ static gpointer namedmutex_create (gboolean owned, const gunichar2 *name)
                handle = mutex_handle_create ((MonoW32HandleMutex*) &namedmutex_handle, MONO_W32HANDLE_NAMEDMUTEX, owned);
        }
 
-       g_free (utf8_name);
-
        mono_w32handle_namespace_unlock ();
 
        return handle;
 }
 
 gpointer
-ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
+ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoStringHandle name, MonoBoolean *created, MonoError *error)
 {
        gpointer mutex;
 
+       error_init (error);
        *created = TRUE;
 
        /* Need to blow away any old errors here, because code tests
@@ -358,13 +355,17 @@ ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoSt
         * was freshly created */
        mono_w32error_set_last (ERROR_SUCCESS);
 
-       if (!name) {
+       if (MONO_HANDLE_IS_NULL (name)) {
                mutex = mutex_create (owned);
        } else {
-               mutex = namedmutex_create (owned, mono_string_chars (name));
+               gchar *utf8_name = mono_string_handle_to_utf8 (name, error);
+               return_val_if_nok (error, NULL);
+
+               mutex = namedmutex_create (owned, utf8_name);
 
                if (mono_w32error_get_last () == ERROR_ALREADY_EXISTS)
                        *created = FALSE;
+               g_free (utf8_name);
        }
 
        return mutex;
index 44b29b5c14bbf1e4175773710cb4c0f6319f7eb5..8d81251f8276387cb857b900da30d25659ecdb11 100644 (file)
@@ -12,6 +12,9 @@
 
 #include <windows.h>
 #include <winbase.h>
+#include <mono/metadata/handle.h>
+#include <mono/utils/mono-error-internals.h>
+
 
 void
 mono_w32mutex_init (void)
@@ -19,19 +22,28 @@ mono_w32mutex_init (void)
 }
 
 gpointer
-ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
+ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoStringHandle name, MonoBoolean *created, MonoError *error)
 {
        HANDLE mutex;
 
+       error_init (error);
+
        *created = TRUE;
 
-       if (!name) {
+       if (MONO_HANDLE_IS_NULL (name)) {
+               MONO_ENTER_GC_SAFE;
                mutex = CreateMutex (NULL, owned, NULL);
+               MONO_EXIT_GC_SAFE;
        } else {
-               mutex = CreateMutex (NULL, owned, mono_string_chars (name));
+               uint32_t gchandle;
+               gunichar2 *uniname = mono_string_handle_pin_chars (name, &gchandle);
+               MONO_ENTER_GC_SAFE;
+               mutex = CreateMutex (NULL, owned, uniname);
 
                if (GetLastError () == ERROR_ALREADY_EXISTS)
                        *created = FALSE;
+               MONO_EXIT_GC_SAFE;
+               mono_gchandle_free (gchandle);
        }
 
        return mutex;
index b80fd1c3ce24d98c9f141f91d35c07fcb94f3a72..f0351ecd5c2255c7b8de4e36bc8103af25c6b2c6 100644 (file)
@@ -9,13 +9,14 @@
 #include <glib.h>
 
 #include "object.h"
+#include "object-internals.h"
 #include "w32handle-namespace.h"
 
 void
 mono_w32mutex_init (void);
 
 gpointer
-ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created);
+ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoStringHandle name, MonoBoolean *created, MonoError *error);
 
 MonoBoolean
 ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle);