aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-27 13:41:30 -0800
committerChris Robinson <[email protected]>2018-11-27 13:41:30 -0800
commitf26083e9edc6491f553aae951886d89b70288528 (patch)
tree1bb2b82ec786cbe2a98a3a5066c0be7c52dff1d1
parent3f745be1dc4df7ffeec89f1d90af41e139fb49db (diff)
Make and use a semaphore class
-rw-r--r--Alc/alc.cpp3
-rw-r--r--Alc/alcontext.h2
-rw-r--r--Alc/alu.cpp6
-rw-r--r--Alc/mixvoice.cpp2
-rw-r--r--OpenAL32/alSource.cpp2
-rw-r--r--OpenAL32/event.cpp4
-rw-r--r--common/threads.cpp50
-rw-r--r--common/threads.h20
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 */