Atuomatically clean up sources with its sublist's destruction
This commit is contained in:
parent
7c0605f09e
commit
bf4518fe5c
10
Alc/alc.cpp
10
Alc/alc.cpp
@ -2598,11 +2598,11 @@ ALCcontext_struct::~ALCcontext_struct()
|
||||
al_free(ActiveAuxSlots.exchange(nullptr, std::memory_order_relaxed));
|
||||
DefaultSlot = nullptr;
|
||||
|
||||
ReleaseALSources(this);
|
||||
std::for_each(SourceList.begin(), SourceList.end(),
|
||||
[](const SourceSubList &entry) noexcept -> void
|
||||
{ al_free(entry.Sources); }
|
||||
);
|
||||
count = 0;
|
||||
for(auto &sublist : SourceList)
|
||||
count += POPCNT64(~sublist.FreeMask);
|
||||
if(count > 0)
|
||||
WARN(SZFMT " Source%s not deleted\n", count, (count==1)?"":"s");
|
||||
SourceList.clear();
|
||||
NumSources = 0;
|
||||
almtx_destroy(&SourceLock);
|
||||
|
@ -44,6 +44,16 @@ enum class DistanceModel {
|
||||
struct SourceSubList {
|
||||
uint64_t FreeMask{~uint64_t{}};
|
||||
ALsource *Sources{nullptr}; /* 64 */
|
||||
|
||||
SourceSubList() noexcept = default;
|
||||
SourceSubList(const SourceSubList&) = delete;
|
||||
SourceSubList(SourceSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Sources{rhs.Sources}
|
||||
{ rhs.FreeMask = ~uint64_t{}; rhs.Sources = nullptr; }
|
||||
~SourceSubList();
|
||||
|
||||
SourceSubList& operator=(const SourceSubList&) = delete;
|
||||
SourceSubList& operator=(SourceSubList&& rhs) noexcept
|
||||
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Sources, rhs.Sources); return *this; }
|
||||
};
|
||||
|
||||
/* Effect slots are rather large, and apps aren't likely to have more than one
|
||||
|
@ -119,8 +119,6 @@ typedef struct ALsource {
|
||||
|
||||
void UpdateAllSourceProps(ALCcontext *context);
|
||||
|
||||
ALvoid ReleaseALSources(ALCcontext *Context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -3399,28 +3399,19 @@ void UpdateAllSourceProps(ALCcontext *context)
|
||||
);
|
||||
}
|
||||
|
||||
/* ReleaseALSources
|
||||
*
|
||||
* Destroys all sources in the source map.
|
||||
*/
|
||||
ALvoid ReleaseALSources(ALCcontext *context)
|
||||
SourceSubList::~SourceSubList()
|
||||
{
|
||||
size_t leftover = 0;
|
||||
for(auto &sublist : context->SourceList)
|
||||
ALuint64 usemask = ~FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALuint64 usemask = ~sublist.FreeMask;
|
||||
while(usemask)
|
||||
{
|
||||
ALsizei idx{CTZ64(usemask)};
|
||||
ALsource *source{sublist.Sources + idx};
|
||||
ALsizei idx{CTZ64(usemask)};
|
||||
ALsource *source{Sources + idx};
|
||||
|
||||
source->~ALsource();
|
||||
++leftover;
|
||||
source->~ALsource();
|
||||
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
sublist.FreeMask = ~usemask;
|
||||
usemask &= ~(U64(1) << idx);
|
||||
}
|
||||
if(leftover > 0)
|
||||
WARN("(%p) Deleted " SZFMT " Source%s\n", context, leftover, (leftover==1)?"":"s");
|
||||
FreeMask = ~usemask;
|
||||
al_free(Sources);
|
||||
Sources = nullptr;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user