Automatically clean up buffers with ther sublist

This commit is contained in:
Chris Robinson 2018-11-25 15:30:32 -08:00
parent 05845b53e8
commit 8ae07ad1ae
5 changed files with 28 additions and 37 deletions

View File

@ -2396,11 +2396,11 @@ ALCdevice_struct::~ALCdevice_struct()
almtx_destroy(&BackendLock);
ReleaseALBuffers(this);
std::for_each(BufferList.begin(), BufferList.end(),
[](BufferSubList &entry) noexcept -> void
{ al_free(entry.Buffers); }
);
size_t count{0u};
for(auto &sublist : BufferList)
count += POPCNT64(~sublist.FreeMask);
if(count > 0)
WARN(SZFMT " Buffer%s not deleted\n", count, (count==1)?"":"s");
BufferList.clear();
almtx_destroy(&BufferLock);

View File

@ -121,6 +121,4 @@ struct ALbuffer {
ALuint id{0};
};
ALvoid ReleaseALBuffers(ALCdevice *device);
#endif

View File

@ -551,10 +551,20 @@ typedef union AmbiConfig {
} AmbiConfig;
typedef struct BufferSubList {
ALuint64 FreeMask{~ALuint64{}};
struct BufferSubList {
uint64_t FreeMask{~uint64_t{}};
struct ALbuffer *Buffers{nullptr}; /* 64 */
} BufferSubList;
BufferSubList() noexcept = default;
BufferSubList(const BufferSubList&) = delete;
BufferSubList(BufferSubList&& rhs) noexcept : FreeMask{rhs.FreeMask}, Buffers{rhs.Buffers}
{ rhs.FreeMask = ~uint64_t{}; rhs.Buffers = nullptr; }
~BufferSubList();
BufferSubList& operator=(const BufferSubList&) = delete;
BufferSubList& operator=(BufferSubList&& rhs) noexcept
{ std::swap(FreeMask, rhs.FreeMask); std::swap(Buffers, rhs.Buffers); return *this; }
};
typedef struct EffectSubList {
ALuint64 FreeMask{~ALuint64{}};

View File

@ -1174,30 +1174,16 @@ ALsizei ChannelsFromFmt(FmtChannels chans)
}
/*
* ReleaseALBuffers()
*
* INTERNAL: Called to destroy any buffers that still exist on the device
*/
ALvoid ReleaseALBuffers(ALCdevice *device)
BufferSubList::~BufferSubList()
{
size_t leftover = 0;
for(auto &sublist : device->BufferList)
ALuint64 usemask = ~FreeMask;
while(usemask)
{
ALuint64 usemask = ~sublist.FreeMask;
while(usemask)
{
ALsizei idx = CTZ64(usemask);
ALbuffer *buffer = sublist.Buffers + idx;
buffer->~ALbuffer();
++leftover;
usemask &= ~(U64(1) << idx);
}
sublist.FreeMask = ~usemask;
ALsizei idx{CTZ64(usemask)};
Buffers[idx].~ALbuffer();
usemask &= ~(U64(1) << idx);
}
if(leftover > 0)
WARN("(%p) Deleted " SZFMT " Buffer%s\n", device, leftover, (leftover==1)?"":"s");
FreeMask = ~usemask;
al_free(Buffers);
Buffers = nullptr;
}

View File

@ -3405,10 +3405,7 @@ SourceSubList::~SourceSubList()
while(usemask)
{
ALsizei idx{CTZ64(usemask)};
ALsource *source{Sources + idx};
source->~ALsource();
Sources[idx].~ALsource();
usemask &= ~(U64(1) << idx);
}
FreeMask = ~usemask;