FreeRDP
Loading...
Searching...
No Matches
mutex.c
1
20#include <winpr/config.h>
21
22#include <winpr/synch.h>
23#include <winpr/debug.h>
24#include <winpr/wlog.h>
25#include <winpr/string.h>
26
27#include "synch.h"
28
29#ifndef _WIN32
30
31#include <errno.h>
32
33#include "../handle/handle.h"
34
35#include "../log.h"
36#define TAG WINPR_TAG("sync.mutex")
37
38static BOOL MutexCloseHandle(HANDLE handle);
39
40static BOOL MutexIsHandled(HANDLE handle)
41{
42 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_MUTEX, FALSE);
43}
44
45static int MutexGetFd(HANDLE handle)
46{
47 WINPR_MUTEX* mux = (WINPR_MUTEX*)handle;
48
49 if (!MutexIsHandled(handle))
50 return -1;
51
52 /* TODO: Mutex does not support file handles... */
53 (void)mux;
54 return -1;
55}
56
57BOOL MutexCloseHandle(HANDLE handle)
58{
59 WINPR_MUTEX* mutex = (WINPR_MUTEX*)handle;
60 int rc = 0;
61
62 if (!MutexIsHandled(handle))
63 return FALSE;
64
65 if ((rc = pthread_mutex_destroy(&mutex->mutex)))
66 {
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)
71 {
72 size_t used = 0;
73 void* stack = winpr_backtrace(20);
74 char** msg = nullptr;
75
76 if (stack)
77 msg = winpr_backtrace_symbols(stack, &used);
78
79 if (msg)
80 {
81 for (size_t i = 0; i < used; i++)
82 WLog_ERR(TAG, "%2" PRIdz ": %s", i, msg[i]);
83 }
84
85 free(msg);
86 winpr_backtrace_free(stack);
87 }
88#endif
93 }
94
95 free(mutex->name);
96 free(handle);
97 return TRUE;
98}
99
100static HANDLE_OPS ops = { MutexIsHandled, MutexCloseHandle, MutexGetFd, nullptr, /* CleanupHandle */
101 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
102 nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
103 nullptr, nullptr, nullptr, nullptr, nullptr };
104
105HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
106{
107 HANDLE handle = nullptr;
108 char* name = nullptr;
109
110 if (lpName)
111 {
112 name = ConvertWCharToUtf8Alloc(lpName, nullptr);
113 if (!name)
114 return nullptr;
115 }
116
117 handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
118 free(name);
119 return handle;
120}
121
122HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
123{
124 HANDLE handle = nullptr;
125 WINPR_MUTEX* mutex = nullptr;
126 mutex = (WINPR_MUTEX*)calloc(1, sizeof(WINPR_MUTEX));
127
128 if (lpMutexAttributes)
129 WLog_WARN(TAG, "[%s] does not support lpMutexAttributes", lpName);
130
131 if (mutex)
132 {
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;
140
141 if (bInitialOwner)
142 pthread_mutex_lock(&mutex->mutex);
143
144 if (lpName)
145 mutex->name = strdup(lpName); /* Non runtime relevant information, skip nullptr check */
146 }
147
148 return handle;
149}
150
151HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
152 DWORD dwDesiredAccess)
153{
154 BOOL initial = FALSE;
155 /* TODO: support access modes */
156
157 if (dwDesiredAccess != 0)
158 WLog_WARN(TAG, "[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
159 dwDesiredAccess);
160
161 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
162 initial = TRUE;
163
164 return CreateMutexA(lpMutexAttributes, initial, lpName);
165}
166
167HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
168 DWORD dwDesiredAccess)
169{
170 BOOL initial = FALSE;
171
172 /* TODO: support access modes */
173 if (dwDesiredAccess != 0)
174 {
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);
178 }
179
180 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
181 initial = TRUE;
182
183 return CreateMutexW(lpMutexAttributes, initial, lpName);
184}
185
186HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
187{
188 /* TODO: Implement */
189 WINPR_UNUSED(dwDesiredAccess);
190 WINPR_UNUSED(bInheritHandle);
191 WINPR_UNUSED(lpName);
192 WLog_ERR(TAG, "TODO: Implement");
193 return nullptr;
194}
195
196HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
197{
198 /* TODO: Implement */
199 WINPR_UNUSED(dwDesiredAccess);
200 WINPR_UNUSED(bInheritHandle);
201 WINPR_UNUSED(lpName);
202 WLog_ERR(TAG, "TODO: Implement");
203 return nullptr;
204}
205
206BOOL ReleaseMutex(HANDLE hMutex)
207{
208 ULONG Type = 0;
209 WINPR_HANDLE* Object = nullptr;
210
211 if (!winpr_Handle_GetInfo(hMutex, &Type, &Object))
212 return FALSE;
213
214 if (Type == HANDLE_TYPE_MUTEX)
215 {
216 WINPR_MUTEX* mutex = (WINPR_MUTEX*)Object;
217 int rc = pthread_mutex_unlock(&mutex->mutex);
218
219 if (rc)
220 {
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);
224 return FALSE;
225 }
226
227 return TRUE;
228 }
229
230 return FALSE;
231}
232
233#endif