aboutsummaryrefslogtreecommitdiffstats
path: root/alc
diff options
context:
space:
mode:
Diffstat (limited to 'alc')
-rw-r--r--alc/alc.cpp70
-rw-r--r--alc/alcmain.h5
-rw-r--r--alc/alcontext.h9
-rw-r--r--alc/alu.cpp24
-rw-r--r--alc/backends/base.cpp4
-rw-r--r--alc/effects/base.h9
-rw-r--r--alc/hrtf.cpp8
7 files changed, 43 insertions, 86 deletions
diff --git a/alc/alc.cpp b/alc/alc.cpp
index 240aca6d..73723f26 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -79,6 +79,7 @@
#include "fpu_modes.h"
#include "hrtf.h"
#include "inprogext.h"
+#include "intrusive_ptr.h"
#include "logging.h"
#include "mastering.h"
#include "opthelpers.h"
@@ -832,9 +833,9 @@ std::atomic<ALCenum> LastNullDeviceError{ALC_NO_ERROR};
/* Thread-local current context */
void ReleaseThreadCtx(ALCcontext *context)
{
- auto ref = DecrementRef(&context->mRef);
- TRACEREF("ALCcontext %p decreasing refcount to %u\n", context, ref);
- ERR("Context %p current for thread being destroyed, possible leak!\n", context);
+ const bool result{context->releaseIfNoDelete()};
+ ERR("Context %p current for thread being destroyed%s!\n", context,
+ result ? "" : ", leak detected");
}
std::atomic<void(*)(ALCcontext*)> ThreadCtxProc{ReleaseThreadCtx};
@@ -907,19 +908,6 @@ constexpr ALCint alcEFXMinorVersion = 0;
al::FlexArray<ALCcontext*> EmptyContextArray{0u};
-void ALCdevice_IncRef(ALCdevice *device)
-{
- auto ref = IncrementRef(&device->ref);
- TRACEREF("ALCdevice %p increasing refcount to %u\n", device, ref);
-}
-
-void ALCdevice_DecRef(ALCdevice *device)
-{
- auto ref = DecrementRef(&device->ref);
- TRACEREF("ALCdevice %p decreasing refcount to %u\n", device, ref);
- if(UNLIKELY(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).
@@ -930,7 +918,7 @@ class DeviceRef {
void reset() noexcept
{
if(mDev)
- ALCdevice_DecRef(mDev);
+ mDev->release();
mDev = nullptr;
}
@@ -1658,10 +1646,10 @@ static std::unique_ptr<Compressor> CreateDeviceLimiter(const ALCdevice *device,
*/
static inline void UpdateClockBase(ALCdevice *device)
{
- IncrementRef(&device->MixCount);
+ IncrementRef(device->MixCount);
device->ClockBase += nanoseconds{seconds{device->SamplesDone}} / device->Frequency;
device->SamplesDone = 0;
- IncrementRef(&device->MixCount);
+ IncrementRef(device->MixCount);
}
/* UpdateDeviceParams
@@ -2205,7 +2193,7 @@ static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
for(s = device->NumAuxSends;s < old_sends;s++)
{
if(source->Send[s].Slot)
- DecrementRef(&source->Send[s].Slot->ref);
+ DecrementRef(source->Send[s].Slot->ref);
source->Send[s].Slot = nullptr;
}
source->Send.resize(device->NumAuxSends);
@@ -2360,7 +2348,7 @@ static DeviceRef VerifyDevice(ALCdevice *device)
auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device);
if(iter != DeviceList.cend() && *iter == device)
{
- ALCdevice_IncRef(iter->get());
+ (*iter)->add_ref();
return DeviceRef{iter->get()};
}
return DeviceRef{};
@@ -2459,7 +2447,7 @@ ALCcontext::~ALCcontext()
while(eprops)
{
ALeffectslotProps *next{eprops->next.load(std::memory_order_relaxed)};
- if(eprops->State) eprops->State->DecRef();
+ if(eprops->State) eprops->State->release();
al_free(eprops);
eprops = next;
++count;
@@ -2528,7 +2516,7 @@ ALCcontext::~ALCcontext()
mAsyncEvents->readAdvance(count);
}
- ALCdevice_DecRef(mDevice);
+ mDevice->release();
}
/* ReleaseContext
@@ -2543,12 +2531,12 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
{
WARN("%p released while current on thread\n", context);
LocalContext.set(nullptr);
- context->decRef();
+ context->release();
}
ALCcontext *origctx{context};
if(GlobalContext.compare_exchange_strong(origctx, nullptr))
- context->decRef();
+ context->release();
bool ret{};
{
@@ -2594,18 +2582,6 @@ static bool ReleaseContext(ALCcontext *context, ALCdevice *device)
return ret;
}
-static void ALCcontext_IncRef(ALCcontext *context)
-{
- auto ref = IncrementRef(&context->mRef);
- TRACEREF("ALCcontext %p increasing refcount to %u\n", context, ref);
-}
-
-void ALCcontext::decRef() noexcept
-{
- auto ref = DecrementRef(&mRef);
- TRACEREF("ALCcontext %p decreasing refcount to %u\n", this, ref);
- if(UNLIKELY(ref == 0)) delete this;
-}
/* VerifyContext
*
@@ -2617,7 +2593,7 @@ static ContextRef VerifyContext(ALCcontext *context)
auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context);
if(iter != ContextList.cend() && *iter == context)
{
- ALCcontext_IncRef(iter->get());
+ (*iter)->add_ref();
return ContextRef{iter->get()};
}
return ContextRef{};
@@ -2632,12 +2608,12 @@ ContextRef GetContextRef(void)
{
ALCcontext *context{LocalContext.get()};
if(context)
- ALCcontext_IncRef(context);
+ context->add_ref();
else
{
std::lock_guard<std::recursive_mutex> _{ListLock};
context = GlobalContext.load(std::memory_order_acquire);
- if(context) ALCcontext_IncRef(context);
+ if(context) context->add_ref();
}
return ContextRef{context};
}
@@ -3278,11 +3254,11 @@ START_API_FUNC
ALuint samplecount;
ALuint refcount;
do {
- while(((refcount=ReadRef(&dev->MixCount))&1) != 0)
+ while(((refcount=ReadRef(dev->MixCount))&1) != 0)
std::this_thread::yield();
basecount = dev->ClockBase;
samplecount = dev->SamplesDone;
- } while(refcount != ReadRef(&dev->MixCount));
+ } while(refcount != ReadRef(dev->MixCount));
basecount += nanoseconds{seconds{samplecount}} / dev->Frequency;
*values = basecount.count();
}
@@ -3426,7 +3402,7 @@ START_API_FUNC
dev->LastError.store(ALC_NO_ERROR);
ContextRef context{new ALCcontext{dev.get()}};
- ALCdevice_IncRef(context->mDevice);
+ dev->add_ref();
ALCenum err{UpdateDeviceParams(dev.get(), attrList)};
if(err != ALC_NO_ERROR)
@@ -3502,7 +3478,7 @@ START_API_FUNC
{
std::lock_guard<std::recursive_mutex> _{ListLock};
auto iter = std::lower_bound(ContextList.cbegin(), ContextList.cend(), context.get());
- ALCcontext_IncRef(context.get());
+ context->add_ref();
ContextList.insert(iter, ContextRef{context.get()});
}
@@ -3850,7 +3826,7 @@ START_API_FUNC
{
std::lock_guard<std::recursive_mutex> _{ListLock};
auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
- ALCdevice_IncRef(device.get());
+ device->add_ref();
DeviceList.insert(iter, DeviceRef{device.get()});
}
@@ -3976,7 +3952,7 @@ START_API_FUNC
{
std::lock_guard<std::recursive_mutex> _{ListLock};
auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
- ALCdevice_IncRef(device.get());
+ device->add_ref();
DeviceList.insert(iter, DeviceRef{device.get()});
}
@@ -4145,7 +4121,7 @@ START_API_FUNC
{
std::lock_guard<std::recursive_mutex> _{ListLock};
auto iter = std::lower_bound(DeviceList.cbegin(), DeviceList.cend(), device.get());
- ALCdevice_IncRef(device.get());
+ device->add_ref();
DeviceList.insert(iter, DeviceRef{device.get()});
}
diff --git a/alc/alcmain.h b/alc/alcmain.h
index f69dc755..5b4e4a2b 100644
--- a/alc/alcmain.h
+++ b/alc/alcmain.h
@@ -24,6 +24,7 @@
#include "atomic.h"
#include "hrtf.h"
#include "inprogext.h"
+#include "intrusive_ptr.h"
#include "vector.h"
class BFormatDec;
@@ -310,9 +311,7 @@ enum {
DeviceFlagsCount
};
-struct ALCdevice {
- RefCount ref{1u};
-
+struct ALCdevice : public al::intrusive_ref<ALCdevice> {
std::atomic<bool> Connected{true};
const DeviceType Type{};
diff --git a/alc/alcontext.h b/alc/alcontext.h
index 43b9c08f..53da10dc 100644
--- a/alc/alcontext.h
+++ b/alc/alcontext.h
@@ -18,6 +18,7 @@
#include "alu.h"
#include "atomic.h"
#include "inprogext.h"
+#include "intrusive_ptr.h"
#include "logging.h"
#include "threads.h"
#include "vector.h"
@@ -84,9 +85,7 @@ struct EffectSlotSubList {
{ std::swap(FreeMask, rhs.FreeMask); std::swap(EffectSlots, rhs.EffectSlots); return *this; }
};
-struct ALCcontext {
- RefCount mRef{1u};
-
+struct ALCcontext : public al::intrusive_ref<ALCcontext> {
al::vector<SourceSubList> mSourceList;
ALuint mNumSources{0};
std::mutex mSourceLock;
@@ -156,8 +155,6 @@ struct ALCcontext {
ALCcontext& operator=(const ALCcontext&) = delete;
~ALCcontext();
- void decRef() noexcept;
-
void allocVoices(size_t num_voices);
/**
@@ -194,7 +191,7 @@ class ContextRef {
void reset() noexcept
{
if(mCtx)
- mCtx->decRef();
+ mCtx->release();
mCtx = nullptr;
}
diff --git a/alc/alu.cpp b/alc/alu.cpp
index 2469d08d..8d627b97 100644
--- a/alc/alu.cpp
+++ b/alc/alu.cpp
@@ -373,20 +373,10 @@ bool CalcEffectSlotParams(ALeffectslot *slot, ALCcontext *context, bool force)
EffectState *oldstate{slot->Params.mEffectState};
slot->Params.mEffectState = state;
- /* Manually decrement the old effect state's refcount if it's greater
- * than 1. We need to be a bit clever here to avoid the refcount
- * reaching 0 since it can't be deleted in the mixer.
+ /* Only decrement the old state if it won't get deleted, since we can't
+ * be deleting/freeing anything in the mixer.
*/
- ALuint oldval{oldstate->mRef.load(std::memory_order_acquire)};
- while(oldval > 1 && !oldstate->mRef.compare_exchange_weak(oldval, oldval-1,
- std::memory_order_acq_rel, std::memory_order_acquire))
- {
- /* oldval was updated with the current value on failure, so just
- * try again.
- */
- }
-
- if(oldval < 2)
+ if(!oldstate->releaseIfNoDelete())
{
/* Otherwise, if it would be deleted, send it off with a release
* event.
@@ -1355,7 +1345,7 @@ void CalcSourceParams(ALvoice *voice, ALCcontext *context, bool force)
void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray *slots)
{
- IncrementRef(&ctx->mUpdateCount);
+ IncrementRef(ctx->mUpdateCount);
if(LIKELY(!ctx->mHoldUpdates.load(std::memory_order_acquire)))
{
bool cforce{CalcContextParams(ctx)};
@@ -1374,7 +1364,7 @@ void ProcessParamUpdates(ALCcontext *ctx, const ALeffectslotArray *slots)
}
);
}
- IncrementRef(&ctx->mUpdateCount);
+ IncrementRef(ctx->mUpdateCount);
}
void ProcessContext(ALCcontext *ctx, const ALsizei SamplesToDo)
@@ -1676,7 +1666,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
);
/* Increment the mix count at the start (lsb should now be 1). */
- IncrementRef(&device->MixCount);
+ IncrementRef(device->MixCount);
/* For each context on this device, process and mix its sources and
* effects.
@@ -1694,7 +1684,7 @@ void aluMixData(ALCdevice *device, ALvoid *OutBuffer, ALsizei NumSamples)
device->SamplesDone %= device->Frequency;
/* Increment the mix count at the end (lsb should now be 0). */
- IncrementRef(&device->MixCount);
+ IncrementRef(device->MixCount);
/* Apply any needed post-process for finalizing the Dry mix to the
* RealOut (Ambisonic decode, UHJ encode, etc).
diff --git a/alc/backends/base.cpp b/alc/backends/base.cpp
index 78b9196e..095990b7 100644
--- a/alc/backends/base.cpp
+++ b/alc/backends/base.cpp
@@ -43,11 +43,11 @@ ClockLatency BackendBase::getClockLatency()
ALuint refcount;
do {
- while(((refcount=mDevice->MixCount.load(std::memory_order_acquire))&1))
+ while(((refcount=ReadRef(mDevice->MixCount))&1) != 0)
std::this_thread::yield();
ret.ClockTime = GetDeviceClockTime(mDevice);
std::atomic_thread_fence(std::memory_order_acquire);
- } while(refcount != mDevice->MixCount.load(std::memory_order_relaxed));
+ } while(refcount != ReadRef(mDevice->MixCount));
/* NOTE: The device will generally have about all but one periods filled at
* any given time during playback. Without a more accurate measurement from
diff --git a/alc/effects/base.h b/alc/effects/base.h
index 4f48de22..89a9e8e4 100644
--- a/alc/effects/base.h
+++ b/alc/effects/base.h
@@ -5,7 +5,7 @@
#include "almalloc.h"
#include "alspan.h"
#include "atomic.h"
-
+#include "intrusive_ptr.h"
struct ALeffectslot;
@@ -149,9 +149,7 @@ struct EffectTarget {
RealMixParams *RealOut;
};
-struct EffectState {
- RefCount mRef{1u};
-
+struct EffectState : public al::intrusive_ref<EffectState> {
al::span<FloatBufferLine> mOutTarget;
@@ -160,9 +158,6 @@ struct EffectState {
virtual ALboolean deviceUpdate(const ALCdevice *device) = 0;
virtual void update(const ALCcontext *context, const ALeffectslot *slot, const EffectProps *props, const EffectTarget target) = 0;
virtual void process(const ALsizei samplesToDo, const FloatBufferLine *RESTRICT samplesIn, const ALsizei numInput, const al::span<FloatBufferLine> samplesOut) = 0;
-
- void IncRef() noexcept;
- void DecRef() noexcept;
};
diff --git a/alc/hrtf.cpp b/alc/hrtf.cpp
index 124707c5..a8b56019 100644
--- a/alc/hrtf.cpp
+++ b/alc/hrtf.cpp
@@ -484,7 +484,7 @@ std::unique_ptr<HrtfEntry> CreateHrtfStore(ALuint rate, ALsizei irSize, const AL
ERR("Out of memory allocating storage for %s.\n", filename);
else
{
- InitRef(&Hrtf->ref, 1u);
+ InitRef(Hrtf->ref, 1u);
Hrtf->sampleRate = rate;
Hrtf->irSize = irSize;
Hrtf->fdCount = fdCount;
@@ -1373,13 +1373,13 @@ HrtfEntry *GetLoadedHrtf(HrtfHandle *handle)
void HrtfEntry::IncRef()
{
- auto ref = IncrementRef(&this->ref);
+ auto ref = IncrementRef(this->ref);
TRACEREF("HrtfEntry %p increasing refcount to %u\n", this, ref);
}
void HrtfEntry::DecRef()
{
- auto ref = DecrementRef(&this->ref);
+ auto ref = DecrementRef(this->ref);
TRACEREF("HrtfEntry %p decreasing refcount to %u\n", this, ref);
if(ref == 0)
{
@@ -1389,7 +1389,7 @@ void HrtfEntry::DecRef()
auto delete_unused = [](HrtfHandlePtr &handle) -> void
{
HrtfEntry *entry{handle->entry.get()};
- if(entry && ReadRef(&entry->ref) == 0)
+ if(entry && ReadRef(entry->ref) == 0)
{
TRACE("Unloading unused HRTF %s\n", handle->filename.data());
handle->entry = nullptr;