diff options
Diffstat (limited to 'src/sem.c')
-rw-r--r-- | src/sem.c | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/src/sem.c b/src/sem.c deleted file mode 100644 index 4b87297..0000000 --- a/src/sem.c +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2012-2022 David Robillard <d@drobilla.net> -// SPDX-License-Identifier: ISC - -#include "zix/sem.h" - -#include "errno_status.h" -#include "zix_config.h" - -#include "zix/status.h" - -#ifdef __APPLE__ -# include <mach/mach.h> -#elif defined(_WIN32) -# include <limits.h> -# include <windows.h> -#else -# include <errno.h> -# include <semaphore.h> -#endif - -#include <stdint.h> -#include <time.h> - -#ifdef __APPLE__ - -ZixStatus -zix_sem_init(ZixSem* sem, unsigned val) -{ - return semaphore_create( - mach_task_self(), &sem->sem, SYNC_POLICY_FIFO, (int)val) - ? ZIX_STATUS_ERROR - : ZIX_STATUS_SUCCESS; -} - -ZixStatus -zix_sem_destroy(ZixSem* sem) -{ - return semaphore_destroy(mach_task_self(), sem->sem) ? ZIX_STATUS_ERROR - : ZIX_STATUS_SUCCESS; -} - -ZixStatus -zix_sem_post(ZixSem* sem) -{ - return semaphore_signal(sem->sem) ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; -} - -ZixStatus -zix_sem_wait(ZixSem* sem) -{ - kern_return_t r = 0; - while ((r = semaphore_wait(sem->sem)) && r == KERN_ABORTED) { - // Interrupted, try again - } - - return r ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; -} - -ZixStatus -zix_sem_try_wait(ZixSem* sem) -{ - const mach_timespec_t zero = {0, 0}; - const kern_return_t r = semaphore_timedwait(sem->sem, zero); - - return (r == KERN_SUCCESS) ? ZIX_STATUS_SUCCESS - : (r == KERN_OPERATION_TIMED_OUT) ? ZIX_STATUS_UNAVAILABLE - : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_timed_wait(ZixSem* sem, - const uint32_t seconds, - const uint32_t nanoseconds) -{ - const mach_timespec_t interval = {seconds, (clock_res_t)nanoseconds}; - const kern_return_t r = semaphore_timedwait(sem->sem, interval); - - return (r == KERN_SUCCESS) ? ZIX_STATUS_SUCCESS - : (r == KERN_OPERATION_TIMED_OUT) ? ZIX_STATUS_TIMEOUT - : ZIX_STATUS_ERROR; -} - -#elif defined(_WIN32) - -ZixStatus -zix_sem_init(ZixSem* sem, unsigned initial) -{ - sem->sem = CreateSemaphore(NULL, (LONG)initial, LONG_MAX, NULL); - return sem->sem ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_destroy(ZixSem* sem) -{ - return CloseHandle(sem->sem) ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_post(ZixSem* sem) -{ - return ReleaseSemaphore(sem->sem, 1, NULL) ? ZIX_STATUS_SUCCESS - : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_wait(ZixSem* sem) -{ - return WaitForSingleObject(sem->sem, INFINITE) == WAIT_OBJECT_0 - ? ZIX_STATUS_SUCCESS - : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_try_wait(ZixSem* sem) -{ - const DWORD r = WaitForSingleObject(sem->sem, 0); - - return (r == WAIT_OBJECT_0) ? ZIX_STATUS_SUCCESS - : (r == WAIT_TIMEOUT) ? ZIX_STATUS_UNAVAILABLE - : ZIX_STATUS_ERROR; -} - -ZixStatus -zix_sem_timed_wait(ZixSem* sem, - const uint32_t seconds, - const uint32_t nanoseconds) -{ - const uint32_t milliseconds = seconds * 1000U + nanoseconds / 1000000U; - const DWORD r = WaitForSingleObject(sem->sem, milliseconds); - - return (r == WAIT_OBJECT_0) ? ZIX_STATUS_SUCCESS - : (r == WAIT_TIMEOUT) ? ZIX_STATUS_TIMEOUT - : ZIX_STATUS_ERROR; -} - -#else /* !defined(__APPLE__) && !defined(_WIN32) */ - -ZixStatus -zix_sem_init(ZixSem* sem, unsigned initial) -{ - return zix_errno_status_if(sem_init(&sem->sem, 0, initial)); -} - -ZixStatus -zix_sem_destroy(ZixSem* sem) -{ - return zix_errno_status_if(sem_destroy(&sem->sem)); -} - -ZixStatus -zix_sem_post(ZixSem* sem) -{ - return zix_errno_status_if(sem_post(&sem->sem)); -} - -ZixStatus -zix_sem_wait(ZixSem* sem) -{ - int r = 0; - while ((r = sem_wait(&sem->sem)) && errno == EINTR) { - // Interrupted, try again - } - - return zix_errno_status_if(r); -} - -ZixStatus -zix_sem_try_wait(ZixSem* sem) -{ - int r = 0; - while ((r = sem_trywait(&sem->sem)) && errno == EINTR) { - // Interrupted, try again - } - - return zix_errno_status_if(r); -} - -ZixStatus -zix_sem_timed_wait(ZixSem* sem, - const uint32_t seconds, - const uint32_t nanoseconds) -{ -# define NS_PER_SECOND 1000000000L - -# if !USE_CLOCK_GETTIME || !USE_SEM_TIMEDWAIT - return ZIX_STATUS_NOT_SUPPORTED; - -# else - - struct timespec ts = {0, 0}; - - int r = 0; - if (!(r = clock_gettime(CLOCK_REALTIME, &ts))) { - ts.tv_sec += (time_t)seconds; - ts.tv_nsec += (long)nanoseconds; - if (ts.tv_nsec >= NS_PER_SECOND) { - ts.tv_nsec -= NS_PER_SECOND; - ts.tv_sec++; - } - - while ((r = sem_timedwait(&sem->sem, &ts)) && errno == EINTR) { - // Interrupted, try again - } - } - - return zix_errno_status_if(r); -# endif - -# undef NS_PER_SECOND -} - -#endif |