aboutsummaryrefslogtreecommitdiffstats
path: root/Alc/alc.cpp
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2018-11-23 17:54:12 -0800
committerChris Robinson <[email protected]>2018-11-23 17:54:12 -0800
commita7c556f814fdb5c638a969a2ca4e309e0927c615 (patch)
tree2feb31d371e394649c002df3446dedc9afc57546 /Alc/alc.cpp
parentdf057d41181b8acc83cb8f64a7dc118b771f9198 (diff)
Use RAII for device references
Diffstat (limited to 'Alc/alc.cpp')
-rw-r--r--Alc/alc.cpp468
1 files changed, 232 insertions, 236 deletions
diff --git a/Alc/alc.cpp b/Alc/alc.cpp
index 9fcf028a..a53269cd 100644
--- a/Alc/alc.cpp
+++ b/Alc/alc.cpp
@@ -2427,39 +2427,82 @@ ALCdevice_struct::~ALCdevice_struct()
}
-void ALCdevice_IncRef(ALCdevice *device)
+static void ALCdevice_IncRef(ALCdevice *device)
{
auto ref = IncrementRef(&device->ref);
TRACEREF("%p increasing refcount to %u\n", device, ref);
}
-void ALCdevice_DecRef(ALCdevice *device)
+static void ALCdevice_DecRef(ALCdevice *device)
{
auto ref = DecrementRef(&device->ref);
TRACEREF("%p decreasing refcount to %u\n", device, ref);
if(ref == 0) delete device;
}
+/* Simple RAII device reference. Takes the reference of the provided ALCdevice,
+ * and decrements it when leaving scope. Movable (transfer reference) but not
+ * copyable (no new references).
+ */
+class DeviceRef {
+ ALCdevice *mDev{nullptr};
+
+ void reset() noexcept
+ {
+ if(mDev)
+ ALCdevice_DecRef(mDev);
+ mDev = nullptr;
+ }
+
+public:
+ DeviceRef() noexcept = default;
+ DeviceRef(DeviceRef&& rhs) noexcept : mDev{rhs.mDev}
+ { rhs.mDev = nullptr; }
+ explicit DeviceRef(ALCdevice *dev) noexcept : mDev(dev) { }
+ ~DeviceRef() { reset(); }
+
+ DeviceRef& operator=(const DeviceRef&) = delete;
+ DeviceRef& operator=(DeviceRef&& rhs) noexcept
+ {
+ reset();
+ mDev = rhs.mDev;
+ rhs.mDev = nullptr;
+ return *this;
+ }
+
+ operator bool() const noexcept { return mDev != nullptr; }
+
+ ALCdevice* operator->() noexcept { return mDev; }
+ ALCdevice* get() noexcept { return mDev; }
+
+ ALCdevice* release() noexcept
+ {
+ ALCdevice *ret{mDev};
+ mDev = nullptr;
+ return ret;
+ }
+};
+
+
/* VerifyDevice
*
- * Checks if the device handle is valid, and increments its ref count if so.
+ * Checks if the device handle is valid, and returns a new reference if so.
*/
-static ALCboolean VerifyDevice(ALCdevice **device)
+static DeviceRef VerifyDevice(ALCdevice *device)
{
std::lock_guard<std::recursive_mutex> _{ListLock};
ALCdevice *tmpDevice{DeviceList.load()};
while(tmpDevice)
{
- if(tmpDevice == *device)
+ if(tmpDevice == device)
{
ALCdevice_IncRef(tmpDevice);
- return ALC_TRUE;
+ return DeviceRef{tmpDevice};
}
tmpDevice = tmpDevice->next.load(std::memory_order_relaxed);
}
- *device = nullptr;
- return ALC_FALSE;
+ return DeviceRef{};
}
@@ -2832,20 +2875,12 @@ void AllocateVoices(ALCcontext *context, ALsizei num_voices, ALsizei old_sends)
/* alcGetError
*
* Return last ALC generated error code for the given device
-*/
+ */
ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
{
- ALCenum errorCode;
-
- if(VerifyDevice(&device))
- {
- errorCode = device->LastError.exchange(ALC_NO_ERROR);
- ALCdevice_DecRef(device);
- }
- else
- errorCode = LastNullDeviceError.exchange(ALC_NO_ERROR);
-
- return errorCode;
+ DeviceRef dev{VerifyDevice(device)};
+ if(dev) return dev->LastError.exchange(ALC_NO_ERROR);
+ return LastNullDeviceError.exchange(ALC_NO_ERROR);
}
@@ -2889,6 +2924,7 @@ ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *context)
ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
{
const ALCchar *value = nullptr;
+ DeviceRef dev;
switch(param)
{
@@ -2921,11 +2957,9 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
break;
case ALC_ALL_DEVICES_SPECIFIER:
- if(VerifyDevice(&Device))
- {
- value = Device->DeviceName.c_str();
- ALCdevice_DecRef(Device);
- }
+ dev = VerifyDevice(Device);
+ if(dev)
+ value = dev->DeviceName.c_str();
else
{
ProbeAllDevicesList();
@@ -2934,11 +2968,9 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
break;
case ALC_CAPTURE_DEVICE_SPECIFIER:
- if(VerifyDevice(&Device))
- {
- value = Device->DeviceName.c_str();
- ALCdevice_DecRef(Device);
- }
+ dev = VerifyDevice(Device);
+ if(dev)
+ value = dev->DeviceName.c_str();
else
{
ProbeCaptureDeviceList();
@@ -2970,31 +3002,25 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum para
break;
case ALC_EXTENSIONS:
- if(!VerifyDevice(&Device))
- value = alcNoDeviceExtList;
- else
- {
- value = alcExtensionList;
- ALCdevice_DecRef(Device);
- }
+ dev = VerifyDevice(Device);
+ if(dev) value = alcExtensionList;
+ else value = alcNoDeviceExtList;
break;
case ALC_HRTF_SPECIFIER_SOFT:
- if(!VerifyDevice(&Device))
+ dev = VerifyDevice(Device);
+ if(!dev)
alcSetError(nullptr, ALC_INVALID_DEVICE);
else
{
- { std::lock_guard<almtx_t> _{Device->BackendLock};
- value = (Device->HrtfHandle ? Device->HrtfName.c_str() : "");
- }
- ALCdevice_DecRef(Device);
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ value = (dev->HrtfHandle ? dev->HrtfName.c_str() : "");
}
break;
default:
- VerifyDevice(&Device);
- alcSetError(Device, ALC_INVALID_ENUM);
- if(Device) ALCdevice_DecRef(Device);
+ dev = VerifyDevice(Device);
+ alcSetError(dev.get(), ALC_INVALID_ENUM);
break;
}
@@ -3324,23 +3350,22 @@ static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALC
*/
ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
{
- VerifyDevice(&device);
+ DeviceRef dev{VerifyDevice(device)};
if(size <= 0 || values == nullptr)
- alcSetError(device, ALC_INVALID_VALUE);
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
- GetIntegerv(device, param, size, values);
- if(device) ALCdevice_DecRef(device);
+ GetIntegerv(dev.get(), param, size, values);
}
ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
{
- VerifyDevice(&device);
+ DeviceRef dev{VerifyDevice(device)};
if(size <= 0 || values == nullptr)
- alcSetError(device, ALC_INVALID_VALUE);
- else if(!device || device->Type == Capture)
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
+ else if(!dev || dev->Type == Capture)
{
std::vector<ALCint> ivals(size);
- size = GetIntegerv(device, pname, size, ivals.data());
+ size = GetIntegerv(dev.get(), pname, size, ivals.data());
std::copy(ivals.begin(), ivals.begin()+size, values);
}
else /* render device */
@@ -3348,67 +3373,67 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
switch(pname)
{
case ALC_ATTRIBUTES_SIZE:
- *values = NumAttrsForDevice(device)+4;
+ *values = NumAttrsForDevice(dev.get())+4;
break;
case ALC_ALL_ATTRIBUTES:
- if(size < NumAttrsForDevice(device)+4)
- alcSetError(device, ALC_INVALID_VALUE);
+ if(size < NumAttrsForDevice(dev.get())+4)
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
{
ALsizei i{0};
- std::lock_guard<almtx_t> _{device->BackendLock};
+ std::lock_guard<almtx_t> _{dev->BackendLock};
values[i++] = ALC_FREQUENCY;
- values[i++] = device->Frequency;
+ values[i++] = dev->Frequency;
- if(device->Type != Loopback)
+ if(dev->Type != Loopback)
{
values[i++] = ALC_REFRESH;
- values[i++] = device->Frequency / device->UpdateSize;
+ values[i++] = dev->Frequency / dev->UpdateSize;
values[i++] = ALC_SYNC;
values[i++] = ALC_FALSE;
}
else
{
- if(device->FmtChans == DevFmtAmbi3D)
+ if(dev->FmtChans == DevFmtAmbi3D)
{
values[i++] = ALC_AMBISONIC_LAYOUT_SOFT;
- values[i++] = static_cast<ALCint64SOFT>(device->mAmbiLayout);
+ values[i++] = static_cast<ALCint64SOFT>(dev->mAmbiLayout);
values[i++] = ALC_AMBISONIC_SCALING_SOFT;
- values[i++] = static_cast<ALCint64SOFT>(device->mAmbiScale);
+ values[i++] = static_cast<ALCint64SOFT>(dev->mAmbiScale);
values[i++] = ALC_AMBISONIC_ORDER_SOFT;
- values[i++] = device->mAmbiOrder;
+ values[i++] = dev->mAmbiOrder;
}
values[i++] = ALC_FORMAT_CHANNELS_SOFT;
- values[i++] = device->FmtChans;
+ values[i++] = dev->FmtChans;
values[i++] = ALC_FORMAT_TYPE_SOFT;
- values[i++] = device->FmtType;
+ values[i++] = dev->FmtType;
}
values[i++] = ALC_MONO_SOURCES;
- values[i++] = device->NumMonoSources;
+ values[i++] = dev->NumMonoSources;
values[i++] = ALC_STEREO_SOURCES;
- values[i++] = device->NumStereoSources;
+ values[i++] = dev->NumStereoSources;
values[i++] = ALC_MAX_AUXILIARY_SENDS;
- values[i++] = device->NumAuxSends;
+ values[i++] = dev->NumAuxSends;
values[i++] = ALC_HRTF_SOFT;
- values[i++] = (device->HrtfHandle ? ALC_TRUE : ALC_FALSE);
+ values[i++] = (dev->HrtfHandle ? ALC_TRUE : ALC_FALSE);
values[i++] = ALC_HRTF_STATUS_SOFT;
- values[i++] = device->HrtfStatus;
+ values[i++] = dev->HrtfStatus;
values[i++] = ALC_OUTPUT_LIMITER_SOFT;
- values[i++] = device->Limiter ? ALC_TRUE : ALC_FALSE;
+ values[i++] = dev->Limiter ? ALC_TRUE : ALC_FALSE;
- ClockLatency clock{GetClockLatency(device)};
+ ClockLatency clock{GetClockLatency(dev.get())};
values[i++] = ALC_DEVICE_CLOCK_SOFT;
values[i++] = clock.ClockTime.count();
@@ -3420,35 +3445,39 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
break;
case ALC_DEVICE_CLOCK_SOFT:
- { std::lock_guard<almtx_t> _{device->BackendLock};
- std::chrono::nanoseconds basecount;
+ { std::lock_guard<almtx_t> _{dev->BackendLock};
+ using std::chrono::seconds;
+ using std::chrono::nanoseconds;
+ using std::chrono::duration_cast;
+
+ nanoseconds basecount;
ALuint samplecount;
ALuint refcount;
do {
- while(((refcount=ReadRef(&device->MixCount))&1) != 0)
+ while(((refcount=ReadRef(&dev->MixCount))&1) != 0)
althrd_yield();
- basecount = device->ClockBase;
- samplecount = device->SamplesDone;
- } while(refcount != ReadRef(&device->MixCount));
- *values = (basecount + std::chrono::duration_cast<std::chrono::nanoseconds>(
- std::chrono::seconds{samplecount}) / device->Frequency).count();
+ basecount = dev->ClockBase;
+ samplecount = dev->SamplesDone;
+ } while(refcount != ReadRef(&dev->MixCount));
+ *values = (duration_cast<nanoseconds>(seconds{samplecount})/dev->Frequency +
+ basecount).count();
}
break;
case ALC_DEVICE_LATENCY_SOFT:
- { std::lock_guard<almtx_t> _{device->BackendLock};
- ClockLatency clock{GetClockLatency(device)};
+ { std::lock_guard<almtx_t> _{dev->BackendLock};
+ ClockLatency clock{GetClockLatency(dev.get())};
*values = clock.Latency.count();
}
break;
case ALC_DEVICE_CLOCK_LATENCY_SOFT:
if(size < 2)
- alcSetError(device, ALC_INVALID_VALUE);
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
{
- std::lock_guard<almtx_t> _{device->BackendLock};
- ClockLatency clock{GetClockLatency(device)};
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ ClockLatency clock{GetClockLatency(dev.get())};
values[0] = clock.ClockTime.count();
values[1] = clock.Latency.count();
}
@@ -3456,13 +3485,11 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
default:
std::vector<ALCint> ivals(size);
- size = GetIntegerv(device, pname, size, ivals.data());
+ size = GetIntegerv(dev.get(), pname, size, ivals.data());
std::copy(ivals.begin(), ivals.begin()+size, values);
break;
}
}
- if(device)
- ALCdevice_DecRef(device);
}
@@ -3472,24 +3499,19 @@ ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname,
*/
ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
{
- ALCboolean bResult = ALC_FALSE;
-
- VerifyDevice(&device);
-
+ DeviceRef dev{VerifyDevice(device)};
if(!extName)
- alcSetError(device, ALC_INVALID_VALUE);
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
{
size_t len = strlen(extName);
- const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
+ const char *ptr = (dev ? alcExtensionList : alcNoDeviceExtList);
while(ptr && *ptr)
{
if(strncasecmp(ptr, extName, len) == 0 &&
(ptr[len] == '\0' || isspace(ptr[len])))
- {
- bResult = ALC_TRUE;
- break;
- }
+ return ALC_TRUE;
+
if((ptr=strchr(ptr, ' ')) != nullptr)
{
do {
@@ -3498,9 +3520,7 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A
}
}
}
- if(device)
- ALCdevice_DecRef(device);
- return bResult;
+ return ALC_FALSE;
}
@@ -3510,13 +3530,10 @@ ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const A
*/
ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
{
- ALCvoid *ptr = nullptr;
-
if(!funcName)
{
- VerifyDevice(&device);
- alcSetError(device, ALC_INVALID_VALUE);
- if(device) ALCdevice_DecRef(device);
+ DeviceRef dev{VerifyDevice(device)};
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
}
else
{
@@ -3524,14 +3541,11 @@ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar
for(i = 0;i < COUNTOF(alcFunctions);i++)
{
if(strcmp(alcFunctions[i].funcName, funcName) == 0)
- {
- ptr = alcFunctions[i].address;
- break;
- }
+ return alcFunctions[i].address;
}
}
- return ptr;
+ return nullptr;
}
@@ -3541,13 +3555,10 @@ ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar
*/
ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
{
- ALCenum val = 0;
-
if(!enumName)
{
- VerifyDevice(&device);
- alcSetError(device, ALC_INVALID_VALUE);
- if(device) ALCdevice_DecRef(device);
+ DeviceRef dev{VerifyDevice(device)};
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
}
else
{
@@ -3555,14 +3566,11 @@ ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *e
for(i = 0;i < COUNTOF(alcEnumerations);i++)
{
if(strcmp(alcEnumerations[i].enumName, enumName) == 0)
- {
- val = alcEnumerations[i].value;
- break;
- }
+ return alcEnumerations[i].value;
}
}
- return val;
+ return 0;
}
@@ -3581,42 +3589,40 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
* properly cleaned up after being made.
*/
std::unique_lock<std::recursive_mutex> listlock{ListLock};
- if(!VerifyDevice(&device) || device->Type == Capture ||
- !device->Connected.load(std::memory_order_relaxed))
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type == Capture || !dev->Connected.load(std::memory_order_relaxed))
{
listlock.unlock();
- alcSetError(device, ALC_INVALID_DEVICE);
- if(device) ALCdevice_DecRef(device);
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
return nullptr;
}
- std::unique_lock<almtx_t> backlock{device->BackendLock};
+ std::unique_lock<almtx_t> backlock{dev->BackendLock};
listlock.unlock();
- device->LastError.store(ALC_NO_ERROR);
+ dev->LastError.store(ALC_NO_ERROR);
- ALContext = new ALCcontext{device};
+ ALContext = new ALCcontext{dev.get()};
ALCdevice_IncRef(ALContext->Device);
- if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
+ if((err=UpdateDeviceParams(dev.get(), attrList)) != ALC_NO_ERROR)
{
backlock.unlock();
delete ALContext;
ALContext = nullptr;
- alcSetError(device, err);
+ alcSetError(dev.get(), err);
if(err == ALC_INVALID_DEVICE)
{
- V0(device->Backend,lock)();
- aluHandleDisconnect(device, "Device update failure");
- V0(device->Backend,unlock)();
+ V0(dev->Backend,lock)();
+ aluHandleDisconnect(dev.get(), "Device update failure");
+ V0(dev->Backend,unlock)();
}
- ALCdevice_DecRef(device);
return nullptr;
}
- AllocateVoices(ALContext, 256, device->NumAuxSends);
+ AllocateVoices(ALContext, 256, dev->NumAuxSends);
- if(DefaultEffect.type != AL_EFFECT_NULL && device->Type == Playback)
+ if(DefaultEffect.type != AL_EFFECT_NULL && dev->Type == Playback)
{
ALContext->DefaultSlot.reset(new ALeffectslot{});
if(InitEffectSlot(ALContext->DefaultSlot.get()) == AL_NO_ERROR)
@@ -3630,7 +3636,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
InitContext(ALContext);
- if(ConfigValueFloat(device->DeviceName.c_str(), nullptr, "volume-adjust", &valf))
+ if(ConfigValueFloat(dev->DeviceName.c_str(), nullptr, "volume-adjust", &valf))
{
if(!std::isfinite(valf))
ERR("volume-adjust must be finite: %f\n", valf);
@@ -3646,10 +3652,10 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
UpdateListenerProps(ALContext);
{
- ALCcontext *head = device->ContextList.load();
+ ALCcontext *head = dev->ContextList.load();
do {
ALContext->next.store(head, std::memory_order_relaxed);
- } while(!device->ContextList.compare_exchange_weak(head, ALContext));
+ } while(!dev->ContextList.compare_exchange_weak(head, ALContext));
}
backlock.unlock();
@@ -3661,8 +3667,6 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
ERR("Failed to initialize the default effect\n");
}
- ALCdevice_DecRef(device);
-
TRACE("Created context %p\n", ALContext);
return ALContext;
}
@@ -4135,58 +4139,58 @@ ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *device)
ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
{
- if(!VerifyDevice(&device) || device->Type != Capture)
- alcSetError(device, ALC_INVALID_DEVICE);
- else
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Capture)
+ {
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
+ return;
+ }
+
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ if(!dev->Connected.load(std::memory_order_acquire))
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
+ else if(!(dev->Flags&DEVICE_RUNNING))
{
- std::lock_guard<almtx_t> _{device->BackendLock};
- if(!device->Connected.load(std::memory_order_acquire))
- alcSetError(device, ALC_INVALID_DEVICE);
- else if(!(device->Flags&DEVICE_RUNNING))
+ if(V0(dev->Backend,start)())
+ dev->Flags |= DEVICE_RUNNING;
+ else
{
- if(V0(device->Backend,start)())
- device->Flags |= DEVICE_RUNNING;
- else
- {
- aluHandleDisconnect(device, "Device start failure");
- alcSetError(device, ALC_INVALID_DEVICE);
- }
+ aluHandleDisconnect(dev.get(), "Device start failure");
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
}
}
-
- if(device) ALCdevice_DecRef(device);
}
ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
{
- if(!VerifyDevice(&device) || device->Type != Capture)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Capture)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else
{
- std::lock_guard<almtx_t> _{device->BackendLock};
- if((device->Flags&DEVICE_RUNNING))
- V0(device->Backend,stop)();
- device->Flags &= ~DEVICE_RUNNING;
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ if((dev->Flags&DEVICE_RUNNING))
+ V0(dev->Backend,stop)();
+ dev->Flags &= ~DEVICE_RUNNING;
}
-
- if(device) ALCdevice_DecRef(device);
}
ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
{
- if(!VerifyDevice(&device) || device->Type != Capture)
- alcSetError(device, ALC_INVALID_DEVICE);
- else
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Capture)
{
- ALCenum err = ALC_INVALID_VALUE;
- { std::lock_guard<almtx_t> _{device->BackendLock};
- if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
- err = V(device->Backend,captureSamples)(buffer, samples);
- }
- if(err != ALC_NO_ERROR)
- alcSetError(device, err);
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
+ return;
}
- if(device) ALCdevice_DecRef(device);
+
+ ALCenum err{ALC_INVALID_VALUE};
+ { std::lock_guard<almtx_t> _{dev->BackendLock};
+ if(samples >= 0 && V0(dev->Backend,availableSamples)() >= (ALCuint)samples)
+ err = V(dev->Backend,captureSamples)(buffer, samples);
+ }
+ if(err != ALC_NO_ERROR)
+ alcSetError(dev.get(), err);
}
@@ -4267,20 +4271,18 @@ ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceN
*/
ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
{
- ALCboolean ret{ALC_FALSE};
-
- if(!VerifyDevice(&device) || device->Type != Loopback)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Loopback)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else if(freq <= 0)
- alcSetError(device, ALC_INVALID_VALUE);
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
{
if(IsValidALCType(type) && IsValidALCChannels(channels) && freq >= MIN_OUTPUT_RATE)
- ret = ALC_TRUE;
+ return ALC_TRUE;
}
- if(device) ALCdevice_DecRef(device);
- return ret;
+ return ALC_FALSE;
}
/* alcRenderSamplesSOFT
@@ -4290,17 +4292,17 @@ ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device
*/
FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
{
- if(!VerifyDevice(&device) || device->Type != Loopback)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Loopback)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else if(samples < 0 || (samples > 0 && buffer == nullptr))
- alcSetError(device, ALC_INVALID_VALUE);
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
else
{
- V0(device->Backend,lock)();
- aluMixData(device, buffer, samples);
- V0(device->Backend,unlock)();
+ V0(dev->Backend,lock)();
+ aluMixData(dev.get(), buffer, samples);
+ V0(dev->Backend,unlock)();
}
- if(device) ALCdevice_DecRef(device);
}
@@ -4314,17 +4316,17 @@ FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, AL
*/
ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
{
- if(!VerifyDevice(&device) || device->Type != Playback)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Playback)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else
{
- std::lock_guard<almtx_t> _{device->BackendLock};
- if((device->Flags&DEVICE_RUNNING))
- V0(device->Backend,stop)();
- device->Flags &= ~DEVICE_RUNNING;
- device->Flags |= DEVICE_PAUSED;
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ if((dev->Flags&DEVICE_RUNNING))
+ V0(dev->Backend,stop)();
+ dev->Flags &= ~DEVICE_RUNNING;
+ dev->Flags |= DEVICE_PAUSED;
}
- if(device) ALCdevice_DecRef(device);
}
/* alcDeviceResumeSOFT
@@ -4333,29 +4335,29 @@ ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
*/
ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
{
- if(!VerifyDevice(&device) || device->Type != Playback)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type != Playback)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else
{
- std::lock_guard<almtx_t> _{device->BackendLock};
- if((device->Flags&DEVICE_PAUSED))
+ std::lock_guard<almtx_t> _{dev->BackendLock};
+ if((dev->Flags&DEVICE_PAUSED))
{
- device->Flags &= ~DEVICE_PAUSED;
- if(device->ContextList.load() != nullptr)
+ dev->Flags &= ~DEVICE_PAUSED;
+ if(dev->ContextList.load() != nullptr)
{
- if(V0(device->Backend,start)() != ALC_FALSE)
- device->Flags |= DEVICE_RUNNING;
+ if(V0(dev->Backend,start)() != ALC_FALSE)
+ dev->Flags |= DEVICE_RUNNING;
else
{
- V0(device->Backend,lock)();
- aluHandleDisconnect(device, "Device start failure");
- V0(device->Backend,unlock)();
- alcSetError(device, ALC_INVALID_DEVICE);
+ V0(dev->Backend,lock)();
+ aluHandleDisconnect(dev.get(), "Device start failure");
+ V0(dev->Backend,unlock)();
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
}
}
}
}
- if(device) ALCdevice_DecRef(device);
}
@@ -4369,26 +4371,23 @@ ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
*/
ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum paramName, ALCsizei index)
{
- const ALCchar *str{nullptr};
-
- if(!VerifyDevice(&device) || device->Type == Capture)
- alcSetError(device, ALC_INVALID_DEVICE);
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type == Capture)
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
else switch(paramName)
{
case ALC_HRTF_SPECIFIER_SOFT:
- if(index >= 0 && (size_t)index < device->HrtfList.size())
- str = device->HrtfList[index].name.c_str();
- else
- alcSetError(device, ALC_INVALID_VALUE);
+ if(index >= 0 && (size_t)index < dev->HrtfList.size())
+ return dev->HrtfList[index].name.c_str();
+ alcSetError(dev.get(), ALC_INVALID_VALUE);
break;
default:
- alcSetError(device, ALC_INVALID_ENUM);
+ alcSetError(dev.get(), ALC_INVALID_ENUM);
break;
}
- if(device) ALCdevice_DecRef(device);
- return str;
+ return nullptr;
}
/* alcResetDeviceSOFT
@@ -4398,33 +4397,30 @@ ALC_API const ALCchar* ALC_APIENTRY alcGetStringiSOFT(ALCdevice *device, ALCenum
ALC_API ALCboolean ALC_APIENTRY alcResetDeviceSOFT(ALCdevice *device, const ALCint *attribs)
{
std::unique_lock<std::recursive_mutex> listlock{ListLock};
- if(!VerifyDevice(&device) || device->Type == Capture ||
- !device->Connected.load(std::memory_order_relaxed))
+ DeviceRef dev{VerifyDevice(device)};
+ if(!dev || dev->Type == Capture || !dev->Connected.load(std::memory_order_relaxed))
{
listlock.unlock();
- alcSetError(device, ALC_INVALID_DEVICE);
- if(device) ALCdevice_DecRef(device);
+ alcSetError(dev.get(), ALC_INVALID_DEVICE);
return ALC_FALSE;
}
- std::unique_lock<almtx_t> backlock{device->BackendLock};
+ std::unique_lock<almtx_t> backlock{dev->BackendLock};
listlock.unlock();
- ALCenum err{UpdateDeviceParams(device, attribs)};
+ ALCenum err{UpdateDeviceParams(dev.get(), attribs)};
backlock.unlock();
if(err != ALC_NO_ERROR)
{
- alcSetError(device, err);
+ alcSetError(dev.get(), err);
if(err == ALC_INVALID_DEVICE)
{
- V0(device->Backend,lock)();
- aluHandleDisconnect(device, "Device start failure");
- V0(device->Backend,unlock)();
+ V0(dev->Backend,lock)();
+ aluHandleDisconnect(dev.get(), "Device start failure");
+ V0(dev->Backend,unlock)();
}
- ALCdevice_DecRef(device);
return ALC_FALSE;
}
- ALCdevice_DecRef(device);
return ALC_TRUE;
}