From 0a0da6cbe1e9c0f8f273f542748f24dc9a9ceea4 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Fri, 26 May 2017 11:08:22 -0400 Subject: [PATCH] [runtime] Use coop handles for ves_icall_System_Threading_Mutex_CreateMutex_internal --- mono/metadata/icall-def.h | 2 +- mono/metadata/w32mutex-unix.c | 19 ++++++++++--------- mono/metadata/w32mutex-win32.c | 18 +++++++++++++++--- mono/metadata/w32mutex.h | 3 ++- 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index d9d7f851714..4efde18a7e1 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -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) diff --git a/mono/metadata/w32mutex-unix.c b/mono/metadata/w32mutex-unix.c index ee3ae7e740d..6e3a5d4f4cd 100644 --- a/mono/metadata/w32mutex-unix.c +++ b/mono/metadata/w32mutex-unix.c @@ -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; diff --git a/mono/metadata/w32mutex-win32.c b/mono/metadata/w32mutex-win32.c index 44b29b5c14b..8d81251f827 100644 --- a/mono/metadata/w32mutex-win32.c +++ b/mono/metadata/w32mutex-win32.c @@ -12,6 +12,9 @@ #include #include +#include +#include + 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; diff --git a/mono/metadata/w32mutex.h b/mono/metadata/w32mutex.h index b80fd1c3ce2..f0351ecd5c2 100644 --- a/mono/metadata/w32mutex.h +++ b/mono/metadata/w32mutex.h @@ -9,13 +9,14 @@ #include #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); -- 2.11.4.GIT