From e240351d81105e233f02d006f6bf42d03c0dd09b Mon Sep 17 00:00:00 2001
From: Chris Robinson <chris.kcat@gmail.com>
Date: Thu, 1 Feb 2018 18:09:16 -0800
Subject: Use a semaphore to signal the event handler

Semaphores allow for semi-persistent signals, compared to a condition variable
which requires a mutex for proper detection. A semaphore can be 'post'ed after
writing some data on one thread, and another thread will be able to recognize
it quickly even if the post occured in between checking for data and waiting.

This more correctly fixes a race condition with events since the mixer
shouldn't be using mutexes, and arbitrary wake-ups just to make sure an event
wasn't missed was quite inefficient.
---
 Alc/ALc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'Alc/ALc.c')

diff --git a/Alc/ALc.c b/Alc/ALc.c
index 632e1f18..8ed10ac6 100644
--- a/Alc/ALc.c
+++ b/Alc/ALc.c
@@ -2613,7 +2613,7 @@ static ALvoid InitContext(ALCcontext *Context)
     ATOMIC_FLAG_TEST_AND_SET(&Context->PropsClean, almemory_order_relaxed);
     ATOMIC_INIT(&Context->DeferUpdates, AL_FALSE);
     almtx_init(&Context->EventThrdLock, almtx_plain);
-    alcnd_init(&Context->EventCnd);
+    alsem_init(&Context->EventSem, 0);
     Context->AsyncEvents = NULL;
     ATOMIC_INIT(&Context->EnabledEvts, 0);
     almtx_init(&Context->EventCbLock, almtx_plain);
@@ -2753,12 +2753,13 @@ static void FreeContext(ALCcontext *context)
         while(ll_ringbuffer_write_space(context->AsyncEvents) == 0)
             althrd_yield();
         ll_ringbuffer_write(context->AsyncEvents, (const char*)&kill_evt, 1);
+        alsem_post(&context->EventSem);
         althrd_join(context->EventThread, NULL);
     }
 
     almtx_destroy(&context->EventCbLock);
     almtx_destroy(&context->EventThrdLock);
-    alcnd_destroy(&context->EventCnd);
+    alsem_destroy(&context->EventSem);
 
     ll_ringbuffer_free(context->AsyncEvents);
     context->AsyncEvents = NULL;
-- 
cgit v1.2.3