Atuomatically clean up sources with its sublist's destruction

This commit is contained in:
Chris Robinson 2018-11-25 08:42:43 -08:00
parent 7c0605f09e
commit bf4518fe5c
4 changed files with 25 additions and 26 deletions

View File

@ -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);

View File

@ -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

View File

@ -119,8 +119,6 @@ typedef struct ALsource {
void UpdateAllSourceProps(ALCcontext *context);
ALvoid ReleaseALSources(ALCcontext *Context);
#ifdef __cplusplus
}
#endif

View File

@ -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;
}