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] = { 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)
71 {
72 size_t used = 0;
73 void* stack = winpr_backtrace(20);
74 char** msg = NULL;
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,
101 MutexCloseHandle,
102 MutexGetFd,
103 NULL, /* CleanupHandle */
104 NULL,
105 NULL,
106 NULL,
107 NULL,
108 NULL,
109 NULL,
110 NULL,
111 NULL,
112 NULL,
113 NULL,
114 NULL,
115 NULL,
116 NULL,
117 NULL,
118 NULL,
119 NULL,
120 NULL };
121
122HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
123{
124 HANDLE handle = NULL;
125 char* name = NULL;
126
127 if (lpName)
128 {
129 name = ConvertWCharToUtf8Alloc(lpName, NULL);
130 if (!name)
131 return NULL;
132 }
133
134 handle = CreateMutexA(lpMutexAttributes, bInitialOwner, name);
135 free(name);
136 return handle;
137}
138
139HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName)
140{
141 HANDLE handle = NULL;
142 WINPR_MUTEX* mutex = NULL;
143 mutex = (WINPR_MUTEX*)calloc(1, sizeof(WINPR_MUTEX));
144
145 if (lpMutexAttributes)
146 WLog_WARN(TAG, "[%s] does not support lpMutexAttributes", lpName);
147
148 if (mutex)
149 {
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;
157
158 if (bInitialOwner)
159 pthread_mutex_lock(&mutex->mutex);
160
161 if (lpName)
162 mutex->name = strdup(lpName); /* Non runtime relevant information, skip NULL check */
163 }
164
165 return handle;
166}
167
168HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, DWORD dwFlags,
169 DWORD dwDesiredAccess)
170{
171 BOOL initial = FALSE;
172 /* TODO: support access modes */
173
174 if (dwDesiredAccess != 0)
175 WLog_WARN(TAG, "[%s] does not support dwDesiredAccess 0x%08" PRIx32, lpName,
176 dwDesiredAccess);
177
178 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
179 initial = TRUE;
180
181 return CreateMutexA(lpMutexAttributes, initial, lpName);
182}
183
184HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, DWORD dwFlags,
185 DWORD dwDesiredAccess)
186{
187 BOOL initial = FALSE;
188
189 /* TODO: support access modes */
190 if (dwDesiredAccess != 0)
191 {
192 char name[MAX_PATH] = { 0 };
193 ConvertWCharToUtf8(lpName, name, sizeof(name) - 1);
194 WLog_WARN(TAG, "[%s] does not support dwDesiredAccess 0x%08" PRIx32, name, dwDesiredAccess);
195 }
196
197 if (dwFlags & CREATE_MUTEX_INITIAL_OWNER)
198 initial = TRUE;
199
200 return CreateMutexW(lpMutexAttributes, initial, lpName);
201}
202
203HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
204{
205 /* TODO: Implement */
206 WINPR_UNUSED(dwDesiredAccess);
207 WINPR_UNUSED(bInheritHandle);
208 WINPR_UNUSED(lpName);
209 WLog_ERR(TAG, "TODO: Implement");
210 return NULL;
211}
212
213HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
214{
215 /* TODO: Implement */
216 WINPR_UNUSED(dwDesiredAccess);
217 WINPR_UNUSED(bInheritHandle);
218 WINPR_UNUSED(lpName);
219 WLog_ERR(TAG, "TODO: Implement");
220 return NULL;
221}
222
223BOOL ReleaseMutex(HANDLE hMutex)
224{
225 ULONG Type = 0;
226 WINPR_HANDLE* Object = NULL;
227
228 if (!winpr_Handle_GetInfo(hMutex, &Type, &Object))
229 return FALSE;
230
231 if (Type == HANDLE_TYPE_MUTEX)
232 {
233 WINPR_MUTEX* mutex = (WINPR_MUTEX*)Object;
234 int rc = pthread_mutex_unlock(&mutex->mutex);
235
236 if (rc)
237 {
238 char ebuffer[256] = { 0 };
239 WLog_ERR(TAG, "pthread_mutex_unlock failed with %s [%d]",
240 winpr_strerror(rc, ebuffer, sizeof(ebuffer)), rc);
241 return FALSE;
242 }
243
244 return TRUE;
245 }
246
247 return FALSE;
248}
249
250#endif