aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2023-12-26 22:37:12 -0800
committerChris Robinson <[email protected]>2023-12-26 22:37:12 -0800
commit205a73876234c0b1363189306530ada73ece56f2 (patch)
tree185ccb4d06ba136e4fee84324c6f1102c184734d
parent1fddc044ac765d00e64628e59edcbcd71f0046b1 (diff)
Try to start being a bit more pointer-owner conscious
-rw-r--r--al/auxeffectslot.cpp25
-rw-r--r--al/buffer.cpp3
-rw-r--r--al/effect.cpp3
-rw-r--r--al/filter.cpp3
-rw-r--r--alc/alc.cpp2
-rw-r--r--alc/backends/wave.cpp78
-rw-r--r--alc/context.h4
-rw-r--r--alc/device.h6
-rw-r--r--common/almalloc.cpp12
-rw-r--r--common/almalloc.h59
-rw-r--r--common/flexarray.h4
-rw-r--r--core/context.cpp24
12 files changed, 115 insertions, 108 deletions
diff --git a/al/auxeffectslot.cpp b/al/auxeffectslot.cpp
index 408b742b..ea41a842 100644
--- a/al/auxeffectslot.cpp
+++ b/al/auxeffectslot.cpp
@@ -155,19 +155,17 @@ void AddActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext *co
*/
if(newcount < newarray->size()) UNLIKELY
{
- curarray = newarray;
+ std::unique_ptr<EffectSlotArray> oldarray{newarray};
newarray = EffectSlot::CreatePtrArray(newcount);
- std::copy_n(curarray->begin(), newcount, newarray->begin());
- delete curarray;
- curarray = nullptr;
+ std::copy_n(oldarray->begin(), newcount, newarray->begin());
}
std::uninitialized_fill_n(newarray->end(), newcount, nullptr);
- curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
+ std::unique_ptr<EffectSlotArray> oldarray{context->mActiveAuxSlots.exchange(newarray,
+ std::memory_order_acq_rel)};
std::ignore = context->mDevice->waitForMix();
- std::destroy_n(curarray->end(), curarray->size());
- delete curarray;
+ std::destroy_n(oldarray->end(), oldarray->size());
}
void RemoveActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext *context)
@@ -193,20 +191,17 @@ void RemoveActiveEffectSlots(const al::span<ALeffectslot*> auxslots, ALCcontext
auto newsize = static_cast<size_t>(std::distance(newarray->begin(), new_end));
if(newsize != newarray->size()) LIKELY
{
- curarray = newarray;
+ std::unique_ptr<EffectSlotArray> oldarray{newarray};
newarray = EffectSlot::CreatePtrArray(newsize);
- std::copy_n(curarray->begin(), newsize, newarray->begin());
-
- delete curarray;
- curarray = nullptr;
+ std::copy_n(oldarray->begin(), newsize, newarray->begin());
}
std::uninitialized_fill_n(newarray->end(), newsize, nullptr);
- curarray = context->mActiveAuxSlots.exchange(newarray, std::memory_order_acq_rel);
+ std::unique_ptr<EffectSlotArray> oldarray{context->mActiveAuxSlots.exchange(newarray,
+ std::memory_order_acq_rel)};
std::ignore = context->mDevice->waitForMix();
std::destroy_n(curarray->end(), curarray->size());
- delete curarray;
}
@@ -251,7 +246,7 @@ bool EnsureEffectSlots(ALCcontext *context, size_t needed)
context->mEffectSlotList.emplace_back();
auto sublist = context->mEffectSlotList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->EffectSlots = static_cast<ALeffectslot*>(
+ sublist->EffectSlots = static_cast<gsl::owner<ALeffectslot*>>(
al_calloc(alignof(ALeffectslot), sizeof(ALeffectslot)*64));
if(!sublist->EffectSlots) UNLIKELY
{
diff --git a/al/buffer.cpp b/al/buffer.cpp
index e577e17a..c0f3f348 100644
--- a/al/buffer.cpp
+++ b/al/buffer.cpp
@@ -186,7 +186,8 @@ bool EnsureBuffers(ALCdevice *device, size_t needed)
device->BufferList.emplace_back();
auto sublist = device->BufferList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->Buffers = static_cast<ALbuffer*>(al_calloc(alignof(ALbuffer), sizeof(ALbuffer)*64));
+ sublist->Buffers = static_cast<gsl::owner<ALbuffer*>>(al_calloc(alignof(ALbuffer),
+ sizeof(ALbuffer)*64));
if(!sublist->Buffers) UNLIKELY
{
device->BufferList.pop_back();
diff --git a/al/effect.cpp b/al/effect.cpp
index c33faa2c..c2a2d1b1 100644
--- a/al/effect.cpp
+++ b/al/effect.cpp
@@ -134,7 +134,8 @@ bool EnsureEffects(ALCdevice *device, size_t needed)
device->EffectList.emplace_back();
auto sublist = device->EffectList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->Effects = static_cast<ALeffect*>(al_calloc(alignof(ALeffect), sizeof(ALeffect)*64));
+ sublist->Effects = static_cast<gsl::owner<ALeffect*>>(al_calloc(alignof(ALeffect),
+ sizeof(ALeffect)*64));
if(!sublist->Effects) UNLIKELY
{
device->EffectList.pop_back();
diff --git a/al/filter.cpp b/al/filter.cpp
index 9c8e4c62..ce37b0aa 100644
--- a/al/filter.cpp
+++ b/al/filter.cpp
@@ -129,7 +129,8 @@ bool EnsureFilters(ALCdevice *device, size_t needed)
device->FilterList.emplace_back();
auto sublist = device->FilterList.end() - 1;
sublist->FreeMask = ~0_u64;
- sublist->Filters = static_cast<ALfilter*>(al_calloc(alignof(ALfilter), sizeof(ALfilter)*64));
+ sublist->Filters = static_cast<gsl::owner<ALfilter*>>(al_calloc(alignof(ALfilter),
+ sizeof(ALfilter)*64));
if(!sublist->Filters) UNLIKELY
{
device->FilterList.pop_back();
diff --git a/alc/alc.cpp b/alc/alc.cpp
index e9d3aed7..64b77080 100644
--- a/alc/alc.cpp
+++ b/alc/alc.cpp
@@ -2735,7 +2735,7 @@ ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCin
if(oldarray != &DeviceBase::sEmptyContextArray)
{
std::ignore = dev->waitForMix();
- delete oldarray;
+ newarray.reset(oldarray);
}
}
statelock.unlock();
diff --git a/alc/backends/wave.cpp b/alc/backends/wave.cpp
index 95064906..60cebd7f 100644
--- a/alc/backends/wave.cpp
+++ b/alc/backends/wave.cpp
@@ -55,6 +55,11 @@ using std::chrono::nanoseconds;
using ubyte = unsigned char;
using ushort = unsigned short;
+struct FileDeleter {
+ void operator()(FILE *f) { fclose(f); }
+};
+using FilePtr = std::unique_ptr<FILE,FileDeleter>;
+
/* NOLINTNEXTLINE(*-avoid-c-arrays) */
constexpr char waveDevice[] = "Wave File Writer";
@@ -102,7 +107,7 @@ struct WaveBackend final : public BackendBase {
void start() override;
void stop() override;
- FILE *mFile{nullptr};
+ FilePtr mFile{nullptr};
long mDataStart{-1};
std::vector<std::byte> mBuffer;
@@ -111,12 +116,7 @@ struct WaveBackend final : public BackendBase {
std::thread mThread;
};
-WaveBackend::~WaveBackend()
-{
- if(mFile)
- fclose(mFile);
- mFile = nullptr;
-}
+WaveBackend::~WaveBackend() = default;
int WaveBackend::mixerProc()
{
@@ -168,8 +168,8 @@ int WaveBackend::mixerProc()
}
}
- const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile)};
- if(fs < mDevice->UpdateSize || ferror(mFile))
+ const size_t fs{fwrite(mBuffer.data(), frameSize, mDevice->UpdateSize, mFile.get())};
+ if(fs < mDevice->UpdateSize || ferror(mFile.get()))
{
ERR("Error writing to file\n");
mDevice->handleDisconnect("Failed to write playback samples");
@@ -211,10 +211,10 @@ void WaveBackend::open(std::string_view name)
#ifdef _WIN32
{
std::wstring wname{utf8_to_wstr(fname.value())};
- mFile = _wfopen(wname.c_str(), L"wb");
+ mFile.reset(_wfopen(wname.c_str(), L"wb"));
}
#else
- mFile = fopen(fname->c_str(), "wb");
+ mFile.reset(fopen(fname->c_str(), "wb"));
#endif
if(!mFile)
throw al::backend_exception{al::backend_error::DeviceError, "Could not open file '%s': %s",
@@ -228,8 +228,8 @@ bool WaveBackend::reset()
uint channels{0}, bytes{0}, chanmask{0};
bool isbformat{false};
- fseek(mFile, 0, SEEK_SET);
- clearerr(mFile);
+ fseek(mFile.get(), 0, SEEK_SET);
+ clearerr(mFile.get());
if(GetConfigValueBool({}, "wave", "bformat", false))
{
@@ -280,48 +280,48 @@ bool WaveBackend::reset()
bytes = mDevice->bytesFromFmt();
channels = mDevice->channelsFromFmt();
- rewind(mFile);
+ rewind(mFile.get());
- fputs("RIFF", mFile);
- fwrite32le(0xFFFFFFFF, mFile); // 'RIFF' header len; filled in at close
+ fputs("RIFF", mFile.get());
+ fwrite32le(0xFFFFFFFF, mFile.get()); // 'RIFF' header len; filled in at close
- fputs("WAVE", mFile);
+ fputs("WAVE", mFile.get());
- fputs("fmt ", mFile);
- fwrite32le(40, mFile); // 'fmt ' header len; 40 bytes for EXTENSIBLE
+ fputs("fmt ", mFile.get());
+ fwrite32le(40, mFile.get()); // 'fmt ' header len; 40 bytes for EXTENSIBLE
// 16-bit val, format type id (extensible: 0xFFFE)
- fwrite16le(0xFFFE, mFile);
+ fwrite16le(0xFFFE, mFile.get());
// 16-bit val, channel count
- fwrite16le(static_cast<ushort>(channels), mFile);
+ fwrite16le(static_cast<ushort>(channels), mFile.get());
// 32-bit val, frequency
- fwrite32le(mDevice->Frequency, mFile);
+ fwrite32le(mDevice->Frequency, mFile.get());
// 32-bit val, bytes per second
- fwrite32le(mDevice->Frequency * channels * bytes, mFile);
+ fwrite32le(mDevice->Frequency * channels * bytes, mFile.get());
// 16-bit val, frame size
- fwrite16le(static_cast<ushort>(channels * bytes), mFile);
+ fwrite16le(static_cast<ushort>(channels * bytes), mFile.get());
// 16-bit val, bits per sample
- fwrite16le(static_cast<ushort>(bytes * 8), mFile);
+ fwrite16le(static_cast<ushort>(bytes * 8), mFile.get());
// 16-bit val, extra byte count
- fwrite16le(22, mFile);
+ fwrite16le(22, mFile.get());
// 16-bit val, valid bits per sample
- fwrite16le(static_cast<ushort>(bytes * 8), mFile);
+ fwrite16le(static_cast<ushort>(bytes * 8), mFile.get());
// 32-bit val, channel mask
- fwrite32le(chanmask, mFile);
+ fwrite32le(chanmask, mFile.get());
// 16 byte GUID, sub-type format
std::ignore = fwrite((mDevice->FmtType == DevFmtFloat) ?
(isbformat ? SUBTYPE_BFORMAT_FLOAT.data() : SUBTYPE_FLOAT.data()) :
- (isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile);
+ (isbformat ? SUBTYPE_BFORMAT_PCM.data() : SUBTYPE_PCM.data()), 1, 16, mFile.get());
- fputs("data", mFile);
- fwrite32le(0xFFFFFFFF, mFile); // 'data' header len; filled in at close
+ fputs("data", mFile.get());
+ fwrite32le(0xFFFFFFFF, mFile.get()); // 'data' header len; filled in at close
- if(ferror(mFile))
+ if(ferror(mFile.get()))
{
ERR("Error writing header: %s\n", strerror(errno));
return false;
}
- mDataStart = ftell(mFile);
+ mDataStart = ftell(mFile.get());
setDefaultWFXChannelOrder();
@@ -333,7 +333,7 @@ bool WaveBackend::reset()
void WaveBackend::start()
{
- if(mDataStart > 0 && fseek(mFile, 0, SEEK_END) != 0)
+ if(mDataStart > 0 && fseek(mFile.get(), 0, SEEK_END) != 0)
WARN("Failed to seek on output file\n");
try {
mKillNow.store(false, std::memory_order_release);
@@ -353,14 +353,14 @@ void WaveBackend::stop()
if(mDataStart > 0)
{
- long size{ftell(mFile)};
+ long size{ftell(mFile.get())};
if(size > 0)
{
long dataLen{size - mDataStart};
- if(fseek(mFile, 4, SEEK_SET) == 0)
- fwrite32le(static_cast<uint>(size-8), mFile); // 'WAVE' header len
- if(fseek(mFile, mDataStart-4, SEEK_SET) == 0)
- fwrite32le(static_cast<uint>(dataLen), mFile); // 'data' header len
+ if(fseek(mFile.get(), 4, SEEK_SET) == 0)
+ fwrite32le(static_cast<uint>(size-8), mFile.get()); // 'WAVE' header len
+ if(fseek(mFile.get(), mDataStart-4, SEEK_SET) == 0)
+ fwrite32le(static_cast<uint>(dataLen), mFile.get()); // 'data' header len
}
}
}
diff --git a/alc/context.h b/alc/context.h
index 9f49ceac..d5e5e78b 100644
--- a/alc/context.h
+++ b/alc/context.h
@@ -70,7 +70,7 @@ struct DebugLogEntry {
struct SourceSubList {
uint64_t FreeMask{~0_u64};
- ALsource *Sources{nullptr}; /* 64 */
+ gsl::owner<ALsource*> Sources{nullptr}; /* 64 */
SourceSubList() noexcept = default;
SourceSubList(const SourceSubList&) = delete;
@@ -85,7 +85,7 @@ struct SourceSubList {
struct EffectSlotSubList {
uint64_t FreeMask{~0_u64};
- ALeffectslot *EffectSlots{nullptr}; /* 64 */
+ gsl::owner<ALeffectslot*> EffectSlots{nullptr}; /* 64 */
EffectSlotSubList() noexcept = default;
EffectSlotSubList(const EffectSlotSubList&) = delete;
diff --git a/alc/device.h b/alc/device.h
index 4eb693ff..e5e9b3d2 100644
--- a/alc/device.h
+++ b/alc/device.h
@@ -35,7 +35,7 @@ using uint = unsigned int;
struct BufferSubList {
uint64_t FreeMask{~0_u64};
- ALbuffer *Buffers{nullptr}; /* 64 */
+ gsl::owner<ALbuffer*> Buffers{nullptr}; /* 64 */
BufferSubList() noexcept = default;
BufferSubList(const BufferSubList&) = delete;
@@ -50,7 +50,7 @@ struct BufferSubList {
struct EffectSubList {
uint64_t FreeMask{~0_u64};
- ALeffect *Effects{nullptr}; /* 64 */
+ gsl::owner<ALeffect*> Effects{nullptr}; /* 64 */
EffectSubList() noexcept = default;
EffectSubList(const EffectSubList&) = delete;
@@ -65,7 +65,7 @@ struct EffectSubList {
struct FilterSubList {
uint64_t FreeMask{~0_u64};
- ALfilter *Filters{nullptr}; /* 64 */
+ gsl::owner<ALfilter*> Filters{nullptr}; /* 64 */
FilterSubList() noexcept = default;
FilterSubList(const FilterSubList&) = delete;
diff --git a/common/almalloc.cpp b/common/almalloc.cpp
index ad1dc6be..71953d8b 100644
--- a/common/almalloc.cpp
+++ b/common/almalloc.cpp
@@ -13,13 +13,13 @@
#endif
-void *al_malloc(size_t alignment, size_t size)
+gsl::owner<void*> al_malloc(size_t alignment, size_t size)
{
assert((alignment & (alignment-1)) == 0);
alignment = std::max(alignment, alignof(std::max_align_t));
#if defined(HAVE_POSIX_MEMALIGN)
- void *ret{};
+ gsl::owner<void*> ret{};
if(posix_memalign(&ret, alignment, size) == 0)
return ret;
return nullptr;
@@ -41,14 +41,14 @@ void *al_malloc(size_t alignment, size_t size)
#endif
}
-void *al_calloc(size_t alignment, size_t size)
+gsl::owner<void*> al_calloc(size_t alignment, size_t size)
{
- void *ret{al_malloc(alignment, size)};
+ gsl::owner<void*> ret{al_malloc(alignment, size)};
if(ret) std::memset(ret, 0, size);
return ret;
}
-void al_free(void *ptr) noexcept
+void al_free(gsl::owner<void*> ptr) noexcept
{
#if defined(HAVE_POSIX_MEMALIGN)
std::free(ptr);
@@ -56,6 +56,6 @@ void al_free(void *ptr) noexcept
_aligned_free(ptr);
#else
if(ptr != nullptr)
- std::free(*(static_cast<void**>(ptr) - 1));
+ std::free(*(static_cast<gsl::owner<void*>*>(ptr) - 1));
#endif
}
diff --git a/common/almalloc.h b/common/almalloc.h
index 7ac02bf1..ac4ddfc2 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -13,11 +13,15 @@
#include "pragmadefs.h"
-void al_free(void *ptr) noexcept;
+namespace gsl {
+template<typename T> using owner = T;
+};
+
+void al_free(gsl::owner<void*> ptr) noexcept;
[[gnu::alloc_align(1), gnu::alloc_size(2), gnu::malloc]]
-void *al_malloc(size_t alignment, size_t size);
+gsl::owner<void*> al_malloc(size_t alignment, size_t size);
[[gnu::alloc_align(1), gnu::alloc_size(2), gnu::malloc]]
-void *al_calloc(size_t alignment, size_t size);
+gsl::owner<void*> al_calloc(size_t alignment, size_t size);
#define DISABLE_ALLOC \
@@ -29,10 +33,10 @@ void *al_calloc(size_t alignment, size_t size);
#define DEF_PLACE_NEWDEL \
void *operator new(size_t) = delete; \
void *operator new[](size_t) = delete; \
- void operator delete(void *block, void*) noexcept { al_free(block); } \
- void operator delete(void *block) noexcept { al_free(block); } \
- void operator delete[](void *block, void*) noexcept { al_free(block); } \
- void operator delete[](void *block) noexcept { al_free(block); }
+ void operator delete(gsl::owner<void*> block, void*) noexcept { al_free(block); } \
+ void operator delete(gsl::owner<void*> block) noexcept { al_free(block); } \
+ void operator delete[](gsl::owner<void*> block, void*) noexcept { al_free(block); } \
+ void operator delete[](gsl::owner<void*> block) noexcept { al_free(block); }
enum FamCount : size_t { };
@@ -45,15 +49,22 @@ enum FamCount : size_t { };
sizeof(T)); \
} \
\
- void *operator new(size_t /*size*/, FamCount count) \
+ gsl::owner<void*> operator new(size_t /*size*/, FamCount count) \
{ \
- if(void *ret{al_malloc(alignof(T), T::Sizeof(count))}) \
- return ret; \
- throw std::bad_alloc(); \
+ const auto align = std::align_val_t(alignof(T)); \
+ return ::new(align) std::byte[T::Sizeof(count)]; \
} \
void *operator new[](size_t /*size*/) = delete; \
- void operator delete(void *block, FamCount) noexcept { al_free(block); } \
- void operator delete(void *block) noexcept { al_free(block); } \
+ void operator delete(gsl::owner<void*> block, FamCount) noexcept \
+ { \
+ const auto align = std::align_val_t(alignof(T)); \
+ ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \
+ } \
+ void operator delete(gsl::owner<void*> block) noexcept \
+ { \
+ const auto align = std::align_val_t(alignof(T)); \
+ ::operator delete[](static_cast<gsl::owner<std::byte*>>(block), align); \
+ } \
void operator delete[](void* /*block*/) = delete;
@@ -61,7 +72,8 @@ namespace al {
template<typename T, std::size_t Align=alignof(T)>
struct allocator {
- static constexpr std::size_t alignment{std::max(Align, alignof(T))};
+ static constexpr auto alignment = std::max(Align, alignof(T));
+ static constexpr auto AlignVal = std::align_val_t(alignment);
using value_type = T;
using reference = T&;
@@ -81,13 +93,13 @@ struct allocator {
template<typename U, std::size_t N>
constexpr explicit allocator(const allocator<U,N>&) noexcept { }
- T *allocate(std::size_t n)
+ gsl::owner<T*> allocate(std::size_t n)
{
if(n > std::numeric_limits<std::size_t>::max()/sizeof(T)) throw std::bad_alloc();
- if(auto p = al_malloc(alignment, n*sizeof(T))) return static_cast<T*>(p);
- throw std::bad_alloc();
+ return reinterpret_cast<gsl::owner<T*>>(::new(AlignVal) std::byte[n*sizeof(T)]);
}
- void deallocate(T *p, std::size_t) noexcept { al_free(p); }
+ void deallocate(gsl::owner<T*> p, std::size_t) noexcept
+ { ::operator delete[](reinterpret_cast<gsl::owner<std::byte*>>(p), AlignVal); }
};
template<typename T, std::size_t N, typename U, std::size_t M>
constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept { return true; }
@@ -111,8 +123,15 @@ constexpr auto to_address(const T &p) noexcept
template<typename T, typename ...Args>
constexpr T* construct_at(T *ptr, Args&& ...args)
- noexcept(std::is_nothrow_constructible<T, Args...>::value)
-{ return ::new(static_cast<void*>(ptr)) T{std::forward<Args>(args)...}; }
+ noexcept(std::is_nothrow_constructible_v<T, Args...>)
+{
+ /* NOLINTBEGIN(cppcoreguidelines-owning-memory) construct_at doesn't
+ * necessarily handle the address from an owner, while placement new
+ * expects to.
+ */
+ return ::new(static_cast<void*>(ptr)) T{std::forward<Args>(args)...};
+ /* NOLINTEND(cppcoreguidelines-owning-memory) */
+}
} // namespace al
diff --git a/common/flexarray.h b/common/flexarray.h
index 9b6fcc63..7975a52a 100644
--- a/common/flexarray.h
+++ b/common/flexarray.h
@@ -74,7 +74,7 @@ struct FlexArray {
{ return Storage_t_::Sizeof(count, base); }
static std::unique_ptr<FlexArray> Create(index_type count)
{
- if(void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))})
+ if(gsl::owner<void*> ptr{al_calloc(alignof(FlexArray), Sizeof(count))})
{
try {
return std::unique_ptr<FlexArray>{::new(ptr) FlexArray{count}};
@@ -87,7 +87,7 @@ struct FlexArray {
throw std::bad_alloc();
}
- FlexArray(index_type size) noexcept(std::is_nothrow_constructible_v<Storage_t_>)
+ FlexArray(index_type size) noexcept(std::is_nothrow_constructible_v<Storage_t_,index_type>)
: mStore{size}
{ }
~FlexArray() = default;
diff --git a/core/context.cpp b/core/context.cpp
index 1415857c..b969583b 100644
--- a/core/context.cpp
+++ b/core/context.cpp
@@ -29,15 +29,12 @@ ContextBase::~ContextBase()
{
size_t count{0};
ContextProps *cprops{mParams.ContextUpdate.exchange(nullptr, std::memory_order_relaxed)};
- if(cprops)
- {
+ if(std::unique_ptr<ContextProps> old{cprops})
++count;
- delete cprops;
- }
+
cprops = mFreeContextProps.exchange(nullptr, std::memory_order_acquire);
- while(cprops)
+ while(std::unique_ptr<ContextProps> old{cprops})
{
- std::unique_ptr<ContextProps> old{cprops};
cprops = old->next.load(std::memory_order_relaxed);
++count;
}
@@ -45,21 +42,17 @@ ContextBase::~ContextBase()
count = 0;
EffectSlotProps *eprops{mFreeEffectslotProps.exchange(nullptr, std::memory_order_acquire)};
- while(eprops)
+ while(std::unique_ptr<EffectSlotProps> old{eprops})
{
- std::unique_ptr<EffectSlotProps> old{eprops};
eprops = old->next.load(std::memory_order_relaxed);
++count;
}
TRACE("Freed %zu AuxiliaryEffectSlot property object%s\n", count, (count==1)?"":"s");
- if(EffectSlotArray *curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)})
- {
+ if(std::unique_ptr<EffectSlotArray> curarray{mActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed)})
std::destroy_n(curarray->end(), curarray->size());
- delete curarray;
- }
- delete mVoices.exchange(nullptr, std::memory_order_relaxed);
+ std::unique_ptr<ContextBase::VoiceArray>{mVoices.exchange(nullptr, std::memory_order_relaxed)};
if(mAsyncEvents)
{
@@ -149,11 +142,8 @@ void ContextBase::allocVoices(size_t addcount)
voice_iter = std::transform(cluster->begin(), cluster->end(), voice_iter,
[](Voice &voice) noexcept -> Voice* { return &voice; });
- if(auto *oldvoices = mVoices.exchange(newarray.release(), std::memory_order_acq_rel))
- {
+ if(std::unique_ptr<ContextBase::VoiceArray> oldvoices{mVoices.exchange(newarray.release(), std::memory_order_acq_rel)})
std::ignore = mDevice->waitForMix();
- delete oldvoices;
- }
}