123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267 |
- /**
- * WinPR: Windows Portable Runtime
- * Synchronization Functions
- *
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <winpr/synch.h>
- #include "synch.h"
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #ifndef _WIN32
- #include <errno.h>
- #include "../handle/handle.h"
- #include "../log.h"
- #define TAG WINPR_TAG("synch.semaphore")
- static BOOL SemaphoreCloseHandle(HANDLE handle);
- static BOOL SemaphoreIsHandled(HANDLE handle)
- {
- WINPR_TIMER* pSemaphore = (WINPR_TIMER*)handle;
- if (!pSemaphore || (pSemaphore->Type != HANDLE_TYPE_SEMAPHORE))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- return TRUE;
- }
- static int SemaphoreGetFd(HANDLE handle)
- {
- WINPR_SEMAPHORE* sem = (WINPR_SEMAPHORE*)handle;
- if (!SemaphoreIsHandled(handle))
- return -1;
- return sem->pipe_fd[0];
- }
- static DWORD SemaphoreCleanupHandle(HANDLE handle)
- {
- int length;
- WINPR_SEMAPHORE* sem = (WINPR_SEMAPHORE*)handle;
- if (!SemaphoreIsHandled(handle))
- return WAIT_FAILED;
- do
- {
- length = read(sem->pipe_fd[0], &length, 1);
- } while (length < 0 && errno == EINTR);
- if (length != 1)
- {
- WLog_ERR(TAG, "semaphore read() failure [%d] %s", errno, strerror(errno));
- return WAIT_FAILED;
- }
- return WAIT_OBJECT_0;
- }
- BOOL SemaphoreCloseHandle(HANDLE handle)
- {
- WINPR_SEMAPHORE* semaphore = (WINPR_SEMAPHORE*)handle;
- if (!SemaphoreIsHandled(handle))
- return FALSE;
- #ifdef WINPR_PIPE_SEMAPHORE
- if (semaphore->pipe_fd[0] != -1)
- {
- close(semaphore->pipe_fd[0]);
- semaphore->pipe_fd[0] = -1;
- if (semaphore->pipe_fd[1] != -1)
- {
- close(semaphore->pipe_fd[1]);
- semaphore->pipe_fd[1] = -1;
- }
- }
- #else
- #if defined __APPLE__
- semaphore_destroy(mach_task_self(), *((winpr_sem_t*)semaphore->sem));
- #else
- sem_destroy((winpr_sem_t*)semaphore->sem);
- #endif
- #endif
- free(semaphore);
- return TRUE;
- }
- static HANDLE_OPS ops = { SemaphoreIsHandled,
- SemaphoreCloseHandle,
- SemaphoreGetFd,
- SemaphoreCleanupHandle,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL };
- HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
- LONG lMaximumCount, LPCWSTR lpName)
- {
- HANDLE handle;
- WINPR_SEMAPHORE* semaphore;
- semaphore = (WINPR_SEMAPHORE*)calloc(1, sizeof(WINPR_SEMAPHORE));
- if (!semaphore)
- return NULL;
- semaphore->pipe_fd[0] = -1;
- semaphore->pipe_fd[1] = -1;
- semaphore->sem = (winpr_sem_t*)NULL;
- semaphore->ops = &ops;
- #ifdef WINPR_PIPE_SEMAPHORE
- if (pipe(semaphore->pipe_fd) < 0)
- {
- WLog_ERR(TAG, "failed to create semaphore");
- free(semaphore);
- return NULL;
- }
- while (lInitialCount > 0)
- {
- if (write(semaphore->pipe_fd[1], "-", 1) != 1)
- {
- close(semaphore->pipe_fd[0]);
- close(semaphore->pipe_fd[1]);
- free(semaphore);
- return NULL;
- }
- lInitialCount--;
- }
- #else
- semaphore->sem = (winpr_sem_t*)malloc(sizeof(winpr_sem_t));
- if (!semaphore->sem)
- {
- WLog_ERR(TAG, "failed to allocate semaphore memory");
- free(semaphore);
- return NULL;
- }
- #if defined __APPLE__
- if (semaphore_create(mach_task_self(), semaphore->sem, SYNC_POLICY_FIFO, lMaximumCount) !=
- KERN_SUCCESS)
- #else
- if (sem_init(semaphore->sem, 0, lMaximumCount) == -1)
- #endif
- {
- WLog_ERR(TAG, "failed to create semaphore");
- free(semaphore->sem);
- free(semaphore);
- return NULL;
- }
- #endif
- WINPR_HANDLE_SET_TYPE_AND_MODE(semaphore, HANDLE_TYPE_SEMAPHORE, WINPR_FD_READ);
- handle = (HANDLE)semaphore;
- return handle;
- }
- HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount,
- LONG lMaximumCount, LPCSTR lpName)
- {
- return CreateSemaphoreW(lpSemaphoreAttributes, lInitialCount, lMaximumCount, NULL);
- }
- HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName)
- {
- WLog_ERR(TAG, "not implemented");
- return NULL;
- }
- HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName)
- {
- WLog_ERR(TAG, "not implemented");
- return NULL;
- }
- BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount)
- {
- ULONG Type;
- WINPR_HANDLE* Object;
- WINPR_SEMAPHORE* semaphore;
- if (!winpr_Handle_GetInfo(hSemaphore, &Type, &Object))
- return FALSE;
- if (Type == HANDLE_TYPE_SEMAPHORE)
- {
- semaphore = (WINPR_SEMAPHORE*)Object;
- #ifdef WINPR_PIPE_SEMAPHORE
- if (semaphore->pipe_fd[0] != -1)
- {
- while (lReleaseCount > 0)
- {
- if (write(semaphore->pipe_fd[1], "-", 1) != 1)
- return FALSE;
- lReleaseCount--;
- }
- }
- #else
- while (lReleaseCount > 0)
- {
- #if defined __APPLE__
- semaphore_signal(*((winpr_sem_t*)semaphore->sem));
- #else
- sem_post((winpr_sem_t*)semaphore->sem);
- #endif
- }
- #endif
- return TRUE;
- }
- WLog_ERR(TAG, "calling %s on a handle that is not a semaphore", __FUNCTION__);
- return FALSE;
- }
- #endif
|