diff options
author | David Robillard <d@drobilla.net> | 2012-02-13 01:01:38 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-02-13 01:01:38 +0000 |
commit | 806dd3218ab67efcc68e25bfe3a68fddfec029b6 (patch) | |
tree | c8cdc9b356d57fcaf7169afa0e8e9cf7b7ec4e50 /plugins/eg-sampler.lv2/zix | |
parent | 651bc82e5d45c534115e85f568319feab95c38f6 (diff) | |
download | lv2-806dd3218ab67efcc68e25bfe3a68fddfec029b6.tar.xz |
Use portable thread implementation.
Diffstat (limited to 'plugins/eg-sampler.lv2/zix')
-rw-r--r-- | plugins/eg-sampler.lv2/zix/sem.h | 32 | ||||
-rw-r--r-- | plugins/eg-sampler.lv2/zix/thread.h | 133 |
2 files changed, 154 insertions, 11 deletions
diff --git a/plugins/eg-sampler.lv2/zix/sem.h b/plugins/eg-sampler.lv2/zix/sem.h index 98117c8..0b2bbb1 100644 --- a/plugins/eg-sampler.lv2/zix/sem.h +++ b/plugins/eg-sampler.lv2/zix/sem.h @@ -23,6 +23,7 @@ # include <windows.h> #else # include <semaphore.h> +# include <errno.h> #endif #include "zix/common.h" @@ -80,7 +81,7 @@ zix_sem_post(ZixSem* sem); Wait until count is > 0, then decrement. Obviously not realtime safe. */ -static inline void +static inline ZixStatus zix_sem_wait(ZixSem* sem); /** @@ -120,10 +121,13 @@ zix_sem_post(ZixSem* sem) semaphore_signal(sem->sem); } -static inline void +static inline ZixStatus zix_sem_wait(ZixSem* sem) { - semaphore_wait(sem->sem); + if (semaphore_wait(sem->sem) != KERN_SUCCESS) { + return ZIX_STATUS_ERROR; + } + return ZIX_STATUS_SUCCESS; } static inline bool @@ -158,10 +162,13 @@ zix_sem_post(ZixSem* sem) ReleaseSemaphore(sem->sem, 1, NULL); } -static inline void +static inline ZixStatus zix_sem_wait(ZixSem* sem) { - WaitForSingleObject(sem->sem, INFINITE); + if (WaitForSingleObject(sem->sem, INFINITE) != WAIT_OBJECT_0) { + return ZIX_STATUS_ERROR; + } + return ZIX_STATUS_SUCCESS; } static inline bool @@ -195,14 +202,17 @@ zix_sem_post(ZixSem* sem) sem_post(&sem->sem); } -static inline void +static inline ZixStatus zix_sem_wait(ZixSem* sem) { - /* Note that sem_wait always returns 0 in practice, except in - gdb (at least), where it returns nonzero, so the while is - necessary (and is the correct/safe solution in any case). - */ - while (sem_wait(&sem->sem) != 0) {} + while (sem_wait(&sem->sem)) { + if (errno != EINTR) { + return ZIX_STATUS_ERROR; + } + /* Otherwise, interrupted, so try again. */ + } + + return ZIX_STATUS_SUCCESS; } static inline bool diff --git a/plugins/eg-sampler.lv2/zix/thread.h b/plugins/eg-sampler.lv2/zix/thread.h new file mode 100644 index 0000000..ff5a727 --- /dev/null +++ b/plugins/eg-sampler.lv2/zix/thread.h @@ -0,0 +1,133 @@ +/* + Copyright 2012 David Robillard <http://drobilla.net> + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef ZIX_THREAD_H +#define ZIX_THREAD_H + +#ifdef _WIN32 +# include <windows.h> +#else +# include <errno.h> +# include <pthread.h> +#endif + +#include "zix/common.h" + +#ifdef __cplusplus +extern "C" { +#else +# include <stdbool.h> +#endif + +/** + @addtogroup zix + @{ + @name Thread + @{ +*/ + +#ifdef _WIN32 +typedef HANDLE ZixThread; +#else +typedef pthread_t ZixThread; +#endif + +/** + Initialize @c thread to a new thread. + + The thread will immediately be launched, calling @c function with @c arg + as the only parameter. +*/ +static inline ZixStatus +zix_thread_create(ZixThread* thread, + size_t stack_size, + void* (*function)(void*), + void* arg); + +/** + Join @c thread (block until @c thread exits). +*/ +static inline ZixStatus +zix_thread_join(ZixThread thread, void** retval); + +#ifdef _WIN32 + +static inline ZixStatus +zix_thread_create(ZixThread* thread, + size_t stack_size, + void* (*function)(void*), + void* arg) +{ + *thread = CreateThread(NULL, stack_size, + (LPTHREAD_START_ROUTINE)function, arg, + 0, NULL); + return *thread ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; +} + +static inline ZixStatus +zix_thread_join(ZixThread thread, void** retval) +{ + return WaitForSingleObject(thread, INFINITE) + ? ZIX_STATUS_SUCCESS : ZIX_STATUS_ERROR; +} + +#else /* !defined(_WIN32) */ + +static inline ZixStatus +zix_thread_create(ZixThread* thread, + size_t stack_size, + void* (*function)(void*), + void* arg) +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setstacksize(&attr, stack_size); + + const int ret = pthread_create(thread, NULL, function, arg); + pthread_attr_destroy(&attr); + + if (ret == EAGAIN) { + return ZIX_STATUS_NO_MEM; + } else if (ret == EINVAL) { + return ZIX_STATUS_BAD_ARG; + } else if (ret == EPERM) { + return ZIX_STATUS_BAD_PERMS; + } else if (ret) { + return ZIX_STATUS_ERROR; + } + + return ZIX_STATUS_SUCCESS; +} + +static inline ZixStatus +zix_thread_join(ZixThread thread, void** retval) +{ + return pthread_join(thread, retval) + ? ZIX_STATUS_ERROR : ZIX_STATUS_SUCCESS; +} + +#endif + +/** + @} + @} +*/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* ZIX_THREAD_H */ |