1 /**
2  * \file
3  * Runtime support for managed Mutex on Win32
4  *
5  * Author:
6  *	Ludovic Henry (luhenry@microsoft.com)
7  *
8  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
9  */
10 
11 #include "w32mutex.h"
12 
13 #include <windows.h>
14 #include <winbase.h>
15 #include <mono/metadata/handle.h>
16 #include <mono/utils/mono-error-internals.h>
17 
18 
19 void
mono_w32mutex_init(void)20 mono_w32mutex_init (void)
21 {
22 }
23 
24 gpointer
ves_icall_System_Threading_Mutex_CreateMutex_internal(MonoBoolean owned,MonoStringHandle name,MonoBoolean * created,MonoError * error)25 ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoStringHandle name, MonoBoolean *created, MonoError *error)
26 {
27 	HANDLE mutex;
28 
29 	error_init (error);
30 
31 	*created = TRUE;
32 
33 	if (MONO_HANDLE_IS_NULL (name)) {
34 		MONO_ENTER_GC_SAFE;
35 		mutex = CreateMutex (NULL, owned, NULL);
36 		MONO_EXIT_GC_SAFE;
37 	} else {
38 		uint32_t gchandle;
39 		gunichar2 *uniname = mono_string_handle_pin_chars (name, &gchandle);
40 		MONO_ENTER_GC_SAFE;
41 		mutex = CreateMutex (NULL, owned, uniname);
42 
43 		if (GetLastError () == ERROR_ALREADY_EXISTS)
44 			*created = FALSE;
45 		MONO_EXIT_GC_SAFE;
46 		mono_gchandle_free (gchandle);
47 	}
48 
49 	return mutex;
50 }
51 
52 MonoBoolean
ves_icall_System_Threading_Mutex_ReleaseMutex_internal(gpointer handle)53 ves_icall_System_Threading_Mutex_ReleaseMutex_internal (gpointer handle)
54 {
55 	return ReleaseMutex (handle);
56 }
57 
58 gpointer
ves_icall_System_Threading_Mutex_OpenMutex_internal(MonoStringHandle name,gint32 rights,gint32 * err,MonoError * error)59 ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoStringHandle name, gint32 rights, gint32 *err, MonoError *error)
60 {
61 	HANDLE ret;
62 
63 	error_init (error);
64 	*err = ERROR_SUCCESS;
65 
66 	uint32_t gchandle = 0;
67 	gunichar2 *uniname = NULL;
68 	if (!MONO_HANDLE_IS_NULL (name))
69 		uniname = mono_string_handle_pin_chars (name, &gchandle);
70 	MONO_ENTER_GC_SAFE;
71 	ret = OpenMutex (rights, FALSE, uniname);
72 	if (!ret)
73 		*err = GetLastError ();
74 	MONO_EXIT_GC_SAFE;
75 	if (gchandle != 0)
76 		mono_gchandle_free (gchandle);
77 
78 	return ret;
79 }
80