From f99b16daa9b38cb2da8717be65db29da2fa518af Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sun, 11 Nov 2018 00:33:04 -0800 Subject: Use C++ threads in the null and wave backends --- Alc/backends/null.cpp | 30 +++++++++++++++++------------- Alc/backends/wave.cpp | 42 +++++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 34 deletions(-) diff --git a/Alc/backends/null.cpp b/Alc/backends/null.cpp index 4c1d3956..ccb1327f 100644 --- a/Alc/backends/null.cpp +++ b/Alc/backends/null.cpp @@ -30,7 +30,6 @@ #include "alMain.h" #include "alu.h" -#include "threads.h" #include "compat.h" #include "backends/base.h" @@ -48,10 +47,10 @@ constexpr ALCchar nullDevice[] = "No Output"; struct ALCnullBackend final : public ALCbackend { ATOMIC(int) killNow; - althrd_t thread; + std::thread thread; }; -static int ALCnullBackend_mixerProc(void *ptr); +static int ALCnullBackend_mixerProc(ALCnullBackend *self); static void ALCnullBackend_Construct(ALCnullBackend *self, ALCdevice *device); static void ALCnullBackend_Destruct(ALCnullBackend *self); @@ -85,9 +84,8 @@ static void ALCnullBackend_Destruct(ALCnullBackend *self) } -static int ALCnullBackend_mixerProc(void *ptr) +static int ALCnullBackend_mixerProc(ALCnullBackend *self) { - ALCnullBackend *self = (ALCnullBackend*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2}; @@ -156,19 +154,25 @@ static ALCboolean ALCnullBackend_reset(ALCnullBackend *self) static ALCboolean ALCnullBackend_start(ALCnullBackend *self) { - ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); - if(althrd_create(&self->thread, ALCnullBackend_mixerProc, self) != althrd_success) - return ALC_FALSE; - return ALC_TRUE; + try { + ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); + self->thread = std::thread(ALCnullBackend_mixerProc, self); + return ALC_TRUE; + } + catch(std::exception& e) { + ERR("Failed to start mixing thread: %s\n", e.what()); + } + catch(...) { + } + return ALC_FALSE; } static void ALCnullBackend_stop(ALCnullBackend *self) { - int res; - - if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel)) + if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel) || + !self->thread.joinable()) return; - althrd_join(self->thread, &res); + self->thread.join(); } diff --git a/Alc/backends/wave.cpp b/Alc/backends/wave.cpp index d5611783..118ed309 100644 --- a/Alc/backends/wave.cpp +++ b/Alc/backends/wave.cpp @@ -31,7 +31,6 @@ #include "alMain.h" #include "alu.h" #include "alconfig.h" -#include "threads.h" #include "compat.h" #include "backends/base.h" @@ -88,10 +87,10 @@ struct ALCwaveBackend final : public ALCbackend { ALuint mSize; ATOMIC(ALenum) killNow; - althrd_t thread; + std::thread thread; }; -static int ALCwaveBackend_mixerProc(void *ptr); +static int ALCwaveBackend_mixerProc(ALCwaveBackend *self); static void ALCwaveBackend_Construct(ALCwaveBackend *self, ALCdevice *device); static void ALCwaveBackend_Destruct(ALCwaveBackend *self); @@ -134,9 +133,8 @@ static void ALCwaveBackend_Destruct(ALCwaveBackend *self) self->~ALCwaveBackend(); } -static int ALCwaveBackend_mixerProc(void *ptr) +static int ALCwaveBackend_mixerProc(ALCwaveBackend *self) { - ALCwaveBackend *self = (ALCwaveBackend*)ptr; ALCdevice *device = STATIC_CAST(ALCbackend, self)->mDevice; const milliseconds restTime{device->UpdateSize*1000/device->Frequency / 2}; @@ -366,35 +364,37 @@ static ALCboolean ALCwaveBackend_start(ALCwaveBackend *self) return ALC_FALSE; } - ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); - if(althrd_create(&self->thread, ALCwaveBackend_mixerProc, self) != althrd_success) - { - free(self->mBuffer); - self->mBuffer = nullptr; - self->mSize = 0; - return ALC_FALSE; + try { + ATOMIC_STORE(&self->killNow, AL_FALSE, almemory_order_release); + self->thread = std::thread(ALCwaveBackend_mixerProc, self); + return ALC_TRUE; + } + catch(std::exception& e) { + ERR("Failed to start mixing thread: %s\n", e.what()); + } + catch(...) { } - return ALC_TRUE; + free(self->mBuffer); + self->mBuffer = nullptr; + self->mSize = 0; + return ALC_FALSE; } static void ALCwaveBackend_stop(ALCwaveBackend *self) { - ALuint dataLen; - long size; - int res; - - if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel)) + if(ATOMIC_EXCHANGE(&self->killNow, AL_TRUE, almemory_order_acq_rel) || + !self->thread.joinable()) return; - althrd_join(self->thread, &res); + self->thread.join(); free(self->mBuffer); self->mBuffer = nullptr; - size = ftell(self->mFile); + long size{ftell(self->mFile)}; if(size > 0) { - dataLen = size - self->mDataStart; + long dataLen{size - self->mDataStart}; if(fseek(self->mFile, self->mDataStart-4, SEEK_SET) == 0) fwrite32le(dataLen, self->mFile); // 'data' header len if(fseek(self->mFile, 4, SEEK_SET) == 0) -- cgit v1.2.3