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")
38 static BOOL MutexCloseHandle(HANDLE handle);
40 static BOOL MutexIsHandled(HANDLE handle)
42 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_MUTEX, FALSE);
45 static int MutexGetFd(HANDLE handle)
47 WINPR_MUTEX* mux = (WINPR_MUTEX*)handle;
49 if (!MutexIsHandled(handle))
57 BOOL 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);
122 HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
124 HANDLE handle = NULL;
129 name = ConvertWCharToUtf8Alloc(lpName, NULL);
134 handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
139 HANDLE 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);
168 HANDLE 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);
184 HANDLE 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);
200 HANDLE 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");
210 HANDLE 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");
220 BOOL 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);