aboutsummaryrefslogtreecommitdiffstats
path: root/al/source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'al/source.cpp')
-rw-r--r--al/source.cpp146
1 files changed, 75 insertions, 71 deletions
diff --git a/al/source.cpp b/al/source.cpp
index a440a04b..bf96a769 100644
--- a/al/source.cpp
+++ b/al/source.cpp
@@ -3407,90 +3407,94 @@ FORCE_ALIGN void AL_APIENTRY alSourceQueueBuffersDirect(ALCcontext *context, ALu
std::unique_lock<std::mutex> buflock{device->BufferLock};
const size_t NewListStart{source->mQueue.size()};
- ALbufferQueueItem *BufferList{nullptr};
- for(ALsizei i{0};i < nb;i++)
- {
- bool fmt_mismatch{false};
- ALbuffer *buffer{buffers[i] ? LookupBuffer(device, buffers[i]) : nullptr};
- if(buffers[i] && !buffer)
- {
- context->setError(AL_INVALID_NAME, "Queueing invalid buffer ID %u", buffers[i]);
- goto buffer_error;
- }
- if(buffer)
+ try {
+ ALbufferQueueItem *BufferList{nullptr};
+ for(ALsizei i{0};i < nb;i++)
{
- if(buffer->mSampleRate < 1)
+ bool fmt_mismatch{false};
+ ALbuffer *buffer{buffers[i] ? LookupBuffer(device, buffers[i]) : nullptr};
+ if(buffers[i] && !buffer)
{
- context->setError(AL_INVALID_OPERATION, "Queueing buffer %u with no format",
- buffer->id);
- goto buffer_error;
+ context->setError(AL_INVALID_NAME, "Queueing invalid buffer ID %u", buffers[i]);
+ throw std::exception{};
}
- if(buffer->mCallback)
+ if(buffer)
{
- context->setError(AL_INVALID_OPERATION, "Queueing callback buffer %u", buffer->id);
- goto buffer_error;
+ if(buffer->mSampleRate < 1)
+ {
+ context->setError(AL_INVALID_OPERATION, "Queueing buffer %u with no format",
+ buffer->id);
+ throw std::exception{};
+ }
+ if(buffer->mCallback)
+ {
+ context->setError(AL_INVALID_OPERATION, "Queueing callback buffer %u",
+ buffer->id);
+ throw std::exception{};
+ }
+ if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
+ {
+ context->setError(AL_INVALID_OPERATION,
+ "Queueing non-persistently mapped buffer %u", buffer->id);
+ throw std::exception{};
+ }
}
- if(buffer->MappedAccess != 0 && !(buffer->MappedAccess&AL_MAP_PERSISTENT_BIT_SOFT))
+
+ source->mQueue.emplace_back();
+ if(!BufferList)
+ BufferList = &source->mQueue.back();
+ else
{
- context->setError(AL_INVALID_OPERATION,
- "Queueing non-persistently mapped buffer %u", buffer->id);
- goto buffer_error;
+ auto &item = source->mQueue.back();
+ BufferList->mNext.store(&item, std::memory_order_relaxed);
+ BufferList = &item;
}
- }
-
- source->mQueue.emplace_back();
- if(!BufferList)
- BufferList = &source->mQueue.back();
- else
- {
- auto &item = source->mQueue.back();
- BufferList->mNext.store(&item, std::memory_order_relaxed);
- BufferList = &item;
- }
- if(!buffer) continue;
- BufferList->mBlockAlign = buffer->mBlockAlign;
- BufferList->mSampleLen = buffer->mSampleLen;
- BufferList->mLoopEnd = buffer->mSampleLen;
- BufferList->mSamples = buffer->mData.data();
- BufferList->mBuffer = buffer;
- IncrementRef(buffer->ref);
-
- if(BufferFmt == nullptr)
- BufferFmt = buffer;
- else
- {
- fmt_mismatch |= BufferFmt->mSampleRate != buffer->mSampleRate;
- fmt_mismatch |= BufferFmt->mChannels != buffer->mChannels;
- fmt_mismatch |= BufferFmt->mType != buffer->mType;
- if(BufferFmt->isBFormat())
+ if(!buffer) continue;
+ BufferList->mBlockAlign = buffer->mBlockAlign;
+ BufferList->mSampleLen = buffer->mSampleLen;
+ BufferList->mLoopEnd = buffer->mSampleLen;
+ BufferList->mSamples = buffer->mData.data();
+ BufferList->mBuffer = buffer;
+ IncrementRef(buffer->ref);
+
+ if(BufferFmt == nullptr)
+ BufferFmt = buffer;
+ else
{
- fmt_mismatch |= BufferFmt->mAmbiLayout != buffer->mAmbiLayout;
- fmt_mismatch |= BufferFmt->mAmbiScaling != buffer->mAmbiScaling;
+ fmt_mismatch |= BufferFmt->mSampleRate != buffer->mSampleRate;
+ fmt_mismatch |= BufferFmt->mChannels != buffer->mChannels;
+ fmt_mismatch |= BufferFmt->mType != buffer->mType;
+ if(BufferFmt->isBFormat())
+ {
+ fmt_mismatch |= BufferFmt->mAmbiLayout != buffer->mAmbiLayout;
+ fmt_mismatch |= BufferFmt->mAmbiScaling != buffer->mAmbiScaling;
+ }
+ fmt_mismatch |= BufferFmt->mAmbiOrder != buffer->mAmbiOrder;
}
- fmt_mismatch |= BufferFmt->mAmbiOrder != buffer->mAmbiOrder;
- }
- if(fmt_mismatch) UNLIKELY
- {
- context->setError(AL_INVALID_OPERATION, "Queueing buffer with mismatched format\n"
- " Expected: %uhz, %s, %s ; Got: %uhz, %s, %s\n", BufferFmt->mSampleRate,
- NameFromFormat(BufferFmt->mType), NameFromFormat(BufferFmt->mChannels),
- buffer->mSampleRate, NameFromFormat(buffer->mType),
- NameFromFormat(buffer->mChannels));
-
- buffer_error:
- /* A buffer failed (invalid ID or format), so unlock and release
- * each buffer we had.
- */
- auto iter = source->mQueue.begin() + ptrdiff_t(NewListStart);
- for(;iter != source->mQueue.end();++iter)
+ if(fmt_mismatch) UNLIKELY
{
- if(ALbuffer *buf{iter->mBuffer})
- DecrementRef(buf->ref);
+ context->setError(AL_INVALID_OPERATION, "Queueing buffer with mismatched format\n"
+ " Expected: %uhz, %s, %s ; Got: %uhz, %s, %s\n", BufferFmt->mSampleRate,
+ NameFromFormat(BufferFmt->mType), NameFromFormat(BufferFmt->mChannels),
+ buffer->mSampleRate, NameFromFormat(buffer->mType),
+ NameFromFormat(buffer->mChannels));
+ throw std::exception{};
}
- source->mQueue.resize(NewListStart);
- return;
}
}
+ catch(...) {
+ /* A buffer failed (invalid ID or format), or there was some other
+ * unexpected error, so unlock and release each buffer we had.
+ */
+ auto iter = source->mQueue.begin() + ptrdiff_t(NewListStart);
+ for(;iter != source->mQueue.end();++iter)
+ {
+ if(ALbuffer *buf{iter->mBuffer})
+ DecrementRef(buf->ref);
+ }
+ source->mQueue.resize(NewListStart);
+ return;
+ }
/* All buffers good. */
buflock.unlock();