Make and use a semaphore class
parent
3f745be1dc
commit
f26083e9ed
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue