aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/event.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-12-25 09:32:38 -0800
committerChris Robinson <[email protected]>2018-12-25 09:32:38 -0800
commit63df7cd537bd43fb2548a112b051a1790ff1140e (patch)
tree99cc9c4ef001c2b3731a4768a8983d7c6f25b47f /OpenAL32/event.cpp
parent3b7f668b28dbc5ef156bad9aa79f16b32efb2eb3 (diff)
Construct AsyncEvent objects directly in the ringbuffer
Diffstat (limited to 'OpenAL32/event.cpp')
-rw-r--r--OpenAL32/event.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/OpenAL32/event.cpp b/OpenAL32/event.cpp
index 6a3dc4bc..6399603b 100644
--- a/OpenAL32/event.cpp
+++ b/OpenAL32/event.cpp
@@ -18,10 +18,10 @@
static int EventThread(ALCcontext *context)
{
bool quitnow{false};
- AsyncEvent evt{};
while(LIKELY(!quitnow))
{
- if(ll_ringbuffer_read(context->AsyncEvents, &evt, 1) == 0)
+ auto evt_data = ll_ringbuffer_get_read_vector(context->AsyncEvents).first;
+ if(evt_data.len == 0)
{
context->EventSem.wait();
continue;
@@ -29,6 +29,22 @@ static int EventThread(ALCcontext *context)
std::lock_guard<std::mutex> _{context->EventCbLock};
do {
+ auto &evt = *reinterpret_cast<AsyncEvent*>(evt_data.buf);
+ evt_data.buf += sizeof(AsyncEvent);
+ evt_data.len -= 1;
+ /* This automatically destructs the event object and advances the
+ * ringbuffer's read offset at the end of scope.
+ */
+ const struct EventAutoDestructor {
+ AsyncEvent &evt;
+ ll_ringbuffer *ring;
+ ~EventAutoDestructor()
+ {
+ evt.~AsyncEvent();
+ ll_ringbuffer_read_advance(ring, 1);
+ }
+ } _{evt, context->AsyncEvents};
+
quitnow = evt.EnumType == EventType_KillThread;
if(UNLIKELY(quitnow)) break;
@@ -73,7 +89,7 @@ static int EventThread(ALCcontext *context)
static_cast<ALsizei>(strlen(evt.u.user.msg)), evt.u.user.msg,
context->EventParam
);
- } while(ll_ringbuffer_read(context->AsyncEvents, &evt, 1) != 0);
+ } while(evt_data.len != 0);
}
return 0;
}
@@ -94,8 +110,17 @@ void StartEventThrd(ALCcontext *ctx)
void StopEventThrd(ALCcontext *ctx)
{
static constexpr AsyncEvent kill_evt{EventType_KillThread};
- while(ll_ringbuffer_write(ctx->AsyncEvents, &kill_evt, 1) == 0)
- std::this_thread::yield();
+ ll_ringbuffer_data evt_data = ll_ringbuffer_get_write_vector(ctx->AsyncEvents).first;
+ if(evt_data.len == 0)
+ {
+ do {
+ std::this_thread::yield();
+ evt_data = ll_ringbuffer_get_write_vector(ctx->AsyncEvents).first;
+ } while(evt_data.len == 0);
+ }
+ new (evt_data.buf) AsyncEvent{kill_evt};
+ ll_ringbuffer_write_advance(ctx->AsyncEvents, 1);
+
ctx->EventSem.post();
if(ctx->EventThread.joinable())
ctx->EventThread.join();