20#include <winpr/config.h>
22#include <winpr/synch.h>
23#include <winpr/debug.h>
24#include <winpr/wlog.h>
25#include <winpr/string.h>
33#include "../handle/handle.h"
36#define TAG WINPR_TAG("sync.mutex")
38static BOOL MutexCloseHandle(HANDLE handle);
40static BOOL MutexIsHandled(HANDLE handle)
42 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_MUTEX, FALSE);
45static int MutexGetFd(HANDLE handle)
47 WINPR_MUTEX* mux = (WINPR_MUTEX*)handle;
49 if (!MutexIsHandled(handle))
57BOOL MutexCloseHandle(HANDLE handle)
59 WINPR_MUTEX* mutex = (WINPR_MUTEX*)handle;
62 if (!MutexIsHandled(handle))
65 if ((rc = pthread_mutex_destroy(&mutex->mutex)))
67 char ebuffer[256] = WINPR_C_ARRAY_INIT;
68 WLog_ERR(TAG,
"pthread_mutex_destroy failed with %s [%d]",
69 winpr_strerror(rc, ebuffer,
sizeof(ebuffer)), rc);
70#if defined(WITH_DEBUG_MUTEX)
73 void* stack = winpr_backtrace(20);
77 msg = winpr_backtrace_symbols(stack, &used);
81 for (
size_t i = 0; i < used; i++)
82 WLog_ERR(TAG,
"%2" PRIdz
": %s", i, msg[i]);
86 winpr_backtrace_free(stack);
100static HANDLE_OPS ops = { MutexIsHandled, MutexCloseHandle, MutexGetFd,
nullptr,
101 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
102 nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
103 nullptr,
nullptr,
nullptr,
nullptr,
nullptr };
105HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
107 HANDLE handle =
nullptr;
108 char* name =
nullptr;
112 name = ConvertWCharToUtf8Alloc(lpName,
nullptr);
117 handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
122HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
124 HANDLE handle =
nullptr;
125 WINPR_MUTEX* mutex =
nullptr;
126 mutex = (WINPR_MUTEX*)calloc(1,
sizeof(WINPR_MUTEX));
128 if (lpMutexAttributes)
129 WLog_WARN(TAG,
"[%s] does not support lpMutexAttributes", lpName);
133 pthread_mutexattr_t attr;
134 pthread_mutexattr_init(&attr);
135 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
136 pthread_mutex_init(&mutex->mutex, &attr);
137 WINPR_HANDLE_SET_TYPE_AND_MODE(mutex, HANDLE_TYPE_MUTEX, WINPR_FD_READ);
138 mutex->common.ops = &ops;
139 handle = (HANDLE)mutex;
142 pthread_mutex_lock(&mutex->mutex);
145 mutex->name = strdup(lpName);
151HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
152 DWORD dwDesiredAccess)
154 BOOL initial = FALSE;
157 if (dwDesiredAccess != 0)
158 WLog_WARN(TAG,
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
161 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
164 return CreateMutexA(lpMutexAttributes, initial, lpName);
167HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
168 DWORD dwDesiredAccess)
170 BOOL initial = FALSE;
173 if (dwDesiredAccess != 0)
175 char name[MAX_PATH] = WINPR_C_ARRAY_INIT;
176 ConvertWCharToUtf8(lpName, name,
sizeof(name) - 1);
177 WLog_WARN(TAG,
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, name, dwDesiredAccess);
180 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
183 return CreateMutexW(lpMutexAttributes, initial, lpName);
186HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
189 WINPR_UNUSED(dwDesiredAccess);
190 WINPR_UNUSED(bInheritHandle);
191 WINPR_UNUSED(lpName);
192 WLog_ERR(TAG,
"TODO: Implement");
196HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
199 WINPR_UNUSED(dwDesiredAccess);
200 WINPR_UNUSED(bInheritHandle);
201 WINPR_UNUSED(lpName);
202 WLog_ERR(TAG,
"TODO: Implement");
206BOOL ReleaseMutex(HANDLE hMutex)
211 if (!winpr_Handle_GetInfo(hMutex, &Type, &Object))
214 if (Type == HANDLE_TYPE_MUTEX)
216 WINPR_MUTEX* mutex = (WINPR_MUTEX*)Object;
217 int rc = pthread_mutex_unlock(&mutex->mutex);
221 char ebuffer[256] = WINPR_C_ARRAY_INIT;
222 WLog_ERR(TAG,
"pthread_mutex_unlock failed with %s [%d]",
223 winpr_strerror(rc, ebuffer,
sizeof(ebuffer)), rc);