diff options
-rw-r--r-- | Alc/alc.cpp | 3 | ||||
-rw-r--r-- | Alc/alcontext.h | 2 | ||||
-rw-r--r-- | Alc/alu.cpp | 6 | ||||
-rw-r--r-- | Alc/mixvoice.cpp | 2 | ||||
-rw-r--r-- | OpenAL32/alSource.cpp | 2 | ||||
-rw-r--r-- | OpenAL32/event.cpp | 4 | ||||
-rw-r--r-- | common/threads.cpp | 50 | ||||
-rw-r--r-- | common/threads.h | 20 |
8 files changed, 59 insertions, 30 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp index ba693616..59ff2306 100644 --- a/Alc/alc.cpp +++ b/Alc/alc.cpp @@ -2528,7 +2528,6 @@ static ALvoid InitContext(ALCcontext *Context) Context->DopplerVelocity = 1.0f; Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC; Context->MetersPerUnit = AL_DEFAULT_METERS_PER_UNIT; - alsem_init(&Context->EventSem, 0); Context->ExtensionList = alExtList; @@ -2642,8 +2641,6 @@ ALCcontext_struct::~ALCcontext_struct() } TRACE("Freed " SZFMT " listener property object%s\n", count, (count==1)?"":"s"); - alsem_destroy(&EventSem); - ll_ringbuffer_free(AsyncEvents); AsyncEvents = nullptr; diff --git a/Alc/alcontext.h b/Alc/alcontext.h index 274888e0..7b7688ac 100644 --- a/Alc/alcontext.h +++ b/Alc/alcontext.h @@ -111,7 +111,7 @@ struct ALCcontext_struct { std::atomic<ALeffectslotArray*> ActiveAuxSlots{nullptr}; std::thread EventThread; - alsem_t EventSem; + al::semaphore EventSem; ll_ringbuffer *AsyncEvents{nullptr}; std::atomic<ALbitfieldSOFT> EnabledEvts{0u}; std::mutex EventCbLock; diff --git a/Alc/alu.cpp b/Alc/alu.cpp index 5036ae24..c7ed0878 100644 --- a/Alc/alu.cpp +++ b/Alc/alu.cpp @@ -313,7 +313,7 @@ void SendSourceStoppedEvent(ALCcontext *context, ALuint id) strcpy(evt.u.user.msg+strpos, " state changed to AL_STOPPED"); if(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) == 1) - alsem_post(&context->EventSem); + context->EventSem.post(); } @@ -441,7 +441,7 @@ bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force) props->State = NULL; if(LIKELY(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) != 0)) - alsem_post(&context->EventSem); + context->EventSem.post(); else { /* If writing the event failed, the queue was probably full. @@ -1857,7 +1857,7 @@ void aluHandleDisconnect(ALCdevice *device, const char *msg, ...) ALbitfieldSOFT enabledevt = ctx->EnabledEvts.load(std::memory_order_acquire); if((enabledevt&EventType_Disconnected) && ll_ringbuffer_write(ctx->AsyncEvents, &evt, 1) == 1) - alsem_post(&ctx->EventSem); + ctx->EventSem.post(); std::for_each(ctx->Voices, ctx->Voices+ctx->VoiceCount.load(std::memory_order_acquire), [ctx](ALvoice *voice) -> void diff --git a/Alc/mixvoice.cpp b/Alc/mixvoice.cpp index 86de61ee..1aa3000b 100644 --- a/Alc/mixvoice.cpp +++ b/Alc/mixvoice.cpp @@ -204,7 +204,7 @@ static void SendAsyncEvent(ALCcontext *context, ALuint enumtype, ALenum type, evt.u.user.param = param; strcpy(evt.u.user.msg, msg); if(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) == 1) - alsem_post(&context->EventSem); + context->EventSem.post(); } diff --git a/OpenAL32/alSource.cpp b/OpenAL32/alSource.cpp index d113ad40..a60701e7 100644 --- a/OpenAL32/alSource.cpp +++ b/OpenAL32/alSource.cpp @@ -705,7 +705,7 @@ void SendStateChangeEvent(ALCcontext *context, ALuint id, ALenum state) * it through the async queue to ensure proper ordering. */ if(ll_ringbuffer_write(context->AsyncEvents, &evt, 1) == 1) - alsem_post(&context->EventSem); + context->EventSem.post(); } diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp index a47787bd..b7599a02 100644 --- a/OpenAL32/event.cpp +++ b/OpenAL32/event.cpp @@ -23,7 +23,7 @@ static int EventThread(ALCcontext *context) AsyncEvent evt; if(ll_ringbuffer_read(context->AsyncEvents, &evt, 1) == 0) { - alsem_wait(&context->EventSem); + context->EventSem.wait(); continue; } @@ -66,7 +66,7 @@ void StopEventThrd(ALCcontext *ctx) static constexpr AsyncEvent kill_evt = ASYNC_EVENT(EventType_KillThread); while(ll_ringbuffer_write(ctx->AsyncEvents, &kill_evt, 1) == 0) std::this_thread::yield(); - alsem_post(&ctx->EventSem); + ctx->EventSem.post(); if(ctx->EventThread.joinable()) ctx->EventThread.join(); } diff --git a/common/threads.cpp b/common/threads.cpp index b4f471d7..c9478871 100644 --- a/common/threads.cpp +++ b/common/threads.cpp @@ -22,25 +22,7 @@ #include "threads.h" -#include <stdlib.h> -#include <string.h> -#include <errno.h> - - -#ifndef UNUSED -#if defined(__cplusplus) -#define UNUSED(x) -#elif defined(__GNUC__) -#define UNUSED(x) UNUSED_##x __attribute__((unused)) -#elif defined(__LCLINT__) -#define UNUSED(x) /*@unused@*/ x -#else -#define UNUSED(x) x -#endif -#endif - - -#define THREAD_STACK_SIZE (2*1024*1024) /* 2MB */ +#include <system_error> #ifdef _WIN32 @@ -116,6 +98,7 @@ int alsem_trywait(alsem_t *sem) #include <sys/time.h> #include <unistd.h> +#include <errno.h> #include <pthread.h> #ifdef HAVE_PTHREAD_NP_H #include <pthread_np.h> @@ -210,3 +193,32 @@ int alsem_trywait(alsem_t *sem) #endif /* __APPLE__ */ #endif + + +namespace al { + +semaphore::semaphore(unsigned int initial) +{ + if(alsem_init(&mSem, initial) != althrd_success) + throw std::system_error(std::make_error_code(std::errc::resource_unavailable_try_again)); +} + +semaphore::~semaphore() +{ alsem_destroy(&mSem); } + +void semaphore::post() +{ + if(alsem_post(&mSem) != althrd_success) + throw std::system_error(std::make_error_code(std::errc::value_too_large)); +} + +void semaphore::wait() noexcept +{ + while(alsem_wait(&mSem) == -2) { + } +} + +int semaphore::trywait() noexcept +{ return alsem_wait(&mSem) == althrd_success; } + +} // namespace al diff --git a/common/threads.h b/common/threads.h index a357b494..03a3899c 100644 --- a/common/threads.h +++ b/common/threads.h @@ -63,6 +63,26 @@ int alsem_trywait(alsem_t *sem); #ifdef __cplusplus } // extern "C" + +namespace al { + +class semaphore { + alsem_t mSem; + +public: + semaphore(unsigned int initial=0); + semaphore(const semaphore&) = delete; + ~semaphore(); + + semaphore& operator=(const semaphore&) = delete; + + void post(); + void wait() noexcept; + int trywait() noexcept; +}; + +} // namespace al + #endif #endif /* AL_THREADS_H */ |