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] = { 0 };
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);
122HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
124 HANDLE handle = NULL;
129 name = ConvertWCharToUtf8Alloc(lpName, NULL);
134 handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
139HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
141 HANDLE handle = NULL;
142 WINPR_MUTEX* mutex = NULL;
143 mutex = (WINPR_MUTEX*)calloc(1,
sizeof(WINPR_MUTEX));
145 if (lpMutexAttributes)
146 WLog_WARN(TAG,
"[%s] does not support lpMutexAttributes", lpName);
150 pthread_mutexattr_t attr;
151 pthread_mutexattr_init(&attr);
152 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
153 pthread_mutex_init(&mutex->mutex, &attr);
154 WINPR_HANDLE_SET_TYPE_AND_MODE(mutex, HANDLE_TYPE_MUTEX, WINPR_FD_READ);
155 mutex->common.ops = &ops;
156 handle = (HANDLE)mutex;
159 pthread_mutex_lock(&mutex->mutex);
162 mutex->name = strdup(lpName);
168HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
169 DWORD dwDesiredAccess)
171 BOOL initial = FALSE;
174 if (dwDesiredAccess != 0)
175 WLog_WARN(TAG,
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
178 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
181 return CreateMutexA(lpMutexAttributes, initial, lpName);
184HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
185 DWORD dwDesiredAccess)
187 BOOL initial = FALSE;
190 if (dwDesiredAccess != 0)
191 WLog_WARN(TAG,
"[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
194 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
197 return CreateMutexW(lpMutexAttributes, initial, lpName);
200HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
203 WINPR_UNUSED(dwDesiredAccess);
204 WINPR_UNUSED(bInheritHandle);
205 WINPR_UNUSED(lpName);
206 WLog_ERR(TAG,
"TODO: Implement");
210HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
213 WINPR_UNUSED(dwDesiredAccess);
214 WINPR_UNUSED(bInheritHandle);
215 WINPR_UNUSED(lpName);
216 WLog_ERR(TAG,
"TODO: Implement");
220BOOL ReleaseMutex(HANDLE hMutex)
225 if (!winpr_Handle_GetInfo(hMutex, &Type, &Object))
228 if (Type == HANDLE_TYPE_MUTEX)
230 WINPR_MUTEX* mutex = (WINPR_MUTEX*)Object;
231 int rc = pthread_mutex_unlock(&mutex->mutex);
235 char ebuffer[256] = { 0 };
236 WLog_ERR(TAG,
"pthread_mutex_unlock failed with %s [%d]",
237 winpr_strerror(rc, ebuffer,
sizeof(ebuffer)), rc);