20 #include <winpr/config.h>
21 #include <winpr/debug.h>
22 #include <winpr/synch.h>
26 #ifdef WINPR_HAVE_UNISTD_H
33 #include "../handle/handle.h"
35 #define TAG WINPR_TAG("synch.semaphore")
37 static BOOL SemaphoreCloseHandle(HANDLE handle);
39 static BOOL SemaphoreIsHandled(HANDLE handle)
41 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_SEMAPHORE, FALSE);
44 static int SemaphoreGetFd(HANDLE handle)
46 WINPR_SEMAPHORE* sem = (WINPR_SEMAPHORE*)handle;
48 if (!SemaphoreIsHandled(handle))
51 return sem->pipe_fd[0];
54 static DWORD SemaphoreCleanupHandle(HANDLE handle)
57 WINPR_SEMAPHORE* sem = (WINPR_SEMAPHORE*)handle;
59 if (!SemaphoreIsHandled(handle))
62 length = read(sem->pipe_fd[0], &length, 1);
66 char ebuffer[256] = { 0 };
67 WLog_ERR(TAG,
"semaphore read() failure [%d] %s", errno,
68 winpr_strerror(errno, ebuffer,
sizeof(ebuffer)));
75 BOOL SemaphoreCloseHandle(HANDLE handle)
77 WINPR_SEMAPHORE* semaphore = (WINPR_SEMAPHORE*)handle;
79 if (!SemaphoreIsHandled(handle))
82 #ifdef WINPR_PIPE_SEMAPHORE
84 if (semaphore->pipe_fd[0] != -1)
86 close(semaphore->pipe_fd[0]);
87 semaphore->pipe_fd[0] = -1;
89 if (semaphore->pipe_fd[1] != -1)
91 close(semaphore->pipe_fd[1]);
92 semaphore->pipe_fd[1] = -1;
98 semaphore_destroy(mach_task_self(), *((winpr_sem_t*)semaphore->sem));
100 sem_destroy((winpr_sem_t*)semaphore->sem);
108 SemaphoreCloseHandle,
110 SemaphoreCleanupHandle,
129 HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
130 LONG lMaximumCount, LPCWSTR lpName)
132 HANDLE handle = NULL;
133 WINPR_SEMAPHORE* semaphore = NULL;
134 semaphore = (WINPR_SEMAPHORE*)calloc(1,
sizeof(WINPR_SEMAPHORE));
139 semaphore->pipe_fd[0] = -1;
140 semaphore->pipe_fd[1] = -1;
141 semaphore->sem = (winpr_sem_t*)NULL;
142 semaphore->common.ops = &ops;
143 #ifdef WINPR_PIPE_SEMAPHORE
145 if (pipe(semaphore->pipe_fd) < 0)
147 WLog_ERR(TAG,
"failed to create semaphore");
152 while (lInitialCount > 0)
154 if (write(semaphore->pipe_fd[1],
"-", 1) != 1)
156 close(semaphore->pipe_fd[0]);
157 close(semaphore->pipe_fd[1]);
166 semaphore->sem = (winpr_sem_t*)malloc(
sizeof(winpr_sem_t));
170 WLog_ERR(TAG,
"failed to allocate semaphore memory");
175 #if defined __APPLE__
177 if (semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount) !=
180 if (sem_init(semaphore->sem, 0, lMaximumCount) == -1)
183 WLog_ERR(TAG,
"failed to create semaphore");
184 free(semaphore->sem);
190 WINPR_HANDLE_SET_TYPE_AND_MODE(semaphore, HANDLE_TYPE_SEMAPHORE, WINPR_FD_READ);
191 handle = (HANDLE)semaphore;
195 HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
196 LONG lMaximumCount, LPCSTR lpName)
198 return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, NULL);
201 HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
203 WLog_ERR(TAG,
"not implemented");
207 HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
209 WLog_ERR(TAG,
"not implemented");
213 BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount)
217 WINPR_SEMAPHORE* semaphore = NULL;
219 if (!winpr_Handle_GetInfo(hSemaphore, &Type, &Object))
222 if (Type == HANDLE_TYPE_SEMAPHORE)
224 semaphore = (WINPR_SEMAPHORE*)Object;
225 #ifdef WINPR_PIPE_SEMAPHORE
227 if (semaphore->pipe_fd[0] != -1)
229 while (lReleaseCount > 0)
231 if (write(semaphore->pipe_fd[1],
"-", 1) != 1)
240 while (lReleaseCount > 0)
242 #if defined __APPLE__
243 semaphore_signal(*((winpr_sem_t*)semaphore->sem));
245 sem_post((winpr_sem_t*)semaphore->sem);
253 WLog_ERR(TAG,
"called on a handle that is not a semaphore");