Never return null from CreateRingBuffer

Allocation failure would already throw a bad_alloc anyway, now a size overflow
throws an exception too.
This commit is contained in:
Chris Robinson 2019-10-08 21:52:08 -07:00
parent 7726a06d26
commit 963580c2d5
11 changed files with 8 additions and 44 deletions

View File

@ -981,10 +981,7 @@ void AlsaCapture::open(const ALCchar *name)
hp = nullptr; hp = nullptr;
if(needring) if(needring)
{
mRing = CreateRingBuffer(mDevice->BufferSize, mDevice->frameSizeFromFmt(), false); mRing = CreateRingBuffer(mDevice->BufferSize, mDevice->frameSizeFromFmt(), false);
if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"};
}
mDevice->DeviceName = name; mDevice->DeviceName = name;
return; return;

View File

@ -570,7 +570,6 @@ void CoreAudioCapture::open(const ALCchar *name)
mDevice->Frequency, Resampler::FastBSinc24); mDevice->Frequency, Resampler::FastBSinc24);
mRing = CreateRingBuffer(outputFrameCount, mFrameSize, false); mRing = CreateRingBuffer(outputFrameCount, mFrameSize, false);
if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to allocate ring buffer"};
mDevice->DeviceName = name; mDevice->DeviceName = name;
} }

View File

@ -743,10 +743,7 @@ void DSoundCapture::open(const ALCchar *name)
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
mDSC->CreateCaptureBuffer(&DSCBDescription, &mDSCbuffer, nullptr); mDSC->CreateCaptureBuffer(&DSCBDescription, &mDSCbuffer, nullptr);
if(SUCCEEDED(hr)) if(SUCCEEDED(hr))
{
mRing = CreateRingBuffer(mDevice->BufferSize, InputType.Format.nBlockAlign, false); mRing = CreateRingBuffer(mDevice->BufferSize, InputType.Format.nBlockAlign, false);
if(!mRing) hr = DSERR_OUTOFMEMORY;
}
if(FAILED(hr)) if(FAILED(hr))
{ {

View File

@ -212,11 +212,7 @@ int JackPlayback::bufferSizeNotify(jack_nframes_t numframes)
mRing = nullptr; mRing = nullptr;
mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true); mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
if(!mRing)
{
ERR("Failed to reallocate ringbuffer\n");
aluHandleDisconnect(mDevice, "Failed to reallocate %u-sample buffer", bufsize);
}
return 0; return 0;
} }
@ -407,11 +403,6 @@ bool JackPlayback::reset()
mRing = nullptr; mRing = nullptr;
mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true); mRing = CreateRingBuffer(bufsize, mDevice->frameSizeFromFmt(), true);
if(!mRing)
{
ERR("Failed to allocate ringbuffer\n");
return false;
}
SetDefaultChannelOrder(mDevice); SetDefaultChannelOrder(mDevice);

View File

@ -521,14 +521,7 @@ bool OpenSLPlayback::reset()
if(SL_RESULT_SUCCESS == result) if(SL_RESULT_SUCCESS == result)
{ {
const ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize}; const ALuint num_updates{mDevice->BufferSize / mDevice->UpdateSize};
try { mRing = CreateRingBuffer(num_updates, mFrameSize*mDevice->UpdateSize, true);
mRing = CreateRingBuffer(num_updates, mFrameSize*mDevice->UpdateSize, true);
}
catch(std::exception& e) {
ERR("Failed allocating ring buffer %ux%ux%u: %s\n", mDevice->UpdateSize,
num_updates, mFrameSize, e.what());
result = SL_RESULT_MEMORY_FAILURE;
}
} }
if(SL_RESULT_SUCCESS != result) if(SL_RESULT_SUCCESS != result)
@ -703,16 +696,10 @@ void OpenSLCapture::open(const ALCchar* name)
mDevice->Frequency/100*5)}; mDevice->Frequency/100*5)};
ALuint num_updates{(length+update_len-1) / update_len}; ALuint num_updates{(length+update_len-1) / update_len};
try { mRing = CreateRingBuffer(num_updates, update_len*mFrameSize, false);
mRing = CreateRingBuffer(num_updates, update_len*mFrameSize, false);
mDevice->UpdateSize = update_len; mDevice->UpdateSize = update_len;
mDevice->BufferSize = static_cast<ALuint>(mRing->writeSpace() * update_len); mDevice->BufferSize = static_cast<ALuint>(mRing->writeSpace() * update_len);
}
catch(std::exception& e) {
ERR("Failed to allocate ring buffer: %s\n", e.what());
result = SL_RESULT_MEMORY_FAILURE;
}
} }
if(SL_RESULT_SUCCESS == result) if(SL_RESULT_SUCCESS == result)
{ {

View File

@ -612,7 +612,6 @@ void OSScapture::open(const ALCchar *name)
ossFormat}; ossFormat};
mRing = CreateRingBuffer(mDevice->BufferSize, frameSize, false); mRing = CreateRingBuffer(mDevice->BufferSize, frameSize, false);
if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"};
mDevice->DeviceName = name; mDevice->DeviceName = name;
} }

View File

@ -286,7 +286,6 @@ void PortCapture::open(const ALCchar *name)
ALuint frame_size{mDevice->frameSizeFromFmt()}; ALuint frame_size{mDevice->frameSizeFromFmt()};
mRing = CreateRingBuffer(samples, frame_size, false); mRing = CreateRingBuffer(samples, frame_size, false);
if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Failed to create ring buffer"};
auto devidopt = ConfigValueInt(nullptr, "port", "capture"); auto devidopt = ConfigValueInt(nullptr, "port", "capture");
if(devidopt && *devidopt >= 0) mParams.device = *devidopt; if(devidopt && *devidopt >= 0) mParams.device = *devidopt;

View File

@ -393,7 +393,6 @@ void SndioCapture::open(const ALCchar *name)
mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate}; mDevice->Frequency, par.sig?'s':'u', par.bits, par.rchan, par.rate};
mRing = CreateRingBuffer(mDevice->BufferSize, par.bps*par.rchan, false); mRing = CreateRingBuffer(mDevice->BufferSize, par.bps*par.rchan, false);
if(!mRing) throw al::backend_exception{ALC_OUT_OF_MEMORY, "Failed to allocate ring buffer"};
SetDefaultChannelOrder(mDevice); SetDefaultChannelOrder(mDevice);

View File

@ -1601,11 +1601,6 @@ HRESULT WasapiCapture::resetProxy()
buffer_len = maxu(mDevice->BufferSize, buffer_len); buffer_len = maxu(mDevice->BufferSize, buffer_len);
mRing = CreateRingBuffer(buffer_len, mDevice->frameSizeFromFmt(), false); mRing = CreateRingBuffer(buffer_len, mDevice->frameSizeFromFmt(), false);
if(!mRing)
{
ERR("Failed to allocate capture ring buffer\n");
return E_OUTOFMEMORY;
}
hr = mClient->SetEventHandle(mNotifyEvent); hr = mClient->SetEventHandle(mNotifyEvent);
if(FAILED(hr)) if(FAILED(hr))

View File

@ -519,7 +519,6 @@ void WinMMCapture::open(const ALCchar *name)
CapturedDataSize = static_cast<ALuint>(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size())); CapturedDataSize = static_cast<ALuint>(maxz(CapturedDataSize, BufferSize*mWaveBuffer.size()));
mRing = CreateRingBuffer(CapturedDataSize, mFormat.nBlockAlign, false); mRing = CreateRingBuffer(CapturedDataSize, mFormat.nBlockAlign, false);
if(!mRing) throw al::backend_exception{ALC_INVALID_VALUE, "Could not create ring buffer"};
al_free(mWaveBuffer[0].lpData); al_free(mWaveBuffer[0].lpData);
mWaveBuffer[0] = WAVEHDR{}; mWaveBuffer[0] = WAVEHDR{};

View File

@ -25,6 +25,7 @@
#include <algorithm> #include <algorithm>
#include <climits> #include <climits>
#include <cstdint> #include <cstdint>
#include <stdexcept>
#include "almalloc.h" #include "almalloc.h"
@ -45,7 +46,8 @@ RingBufferPtr CreateRingBuffer(size_t sz, size_t elem_sz, int limit_writes)
#endif #endif
} }
++power_of_two; ++power_of_two;
if(power_of_two < sz) return nullptr; if(power_of_two <= sz || power_of_two > std::numeric_limits<size_t>::max()/elem_sz)
throw std::overflow_error{"Ring buffer size overflow"};
const size_t bufbytes{power_of_two * elem_sz}; const size_t bufbytes{power_of_two * elem_sz};
RingBufferPtr rb{new (FamCount{bufbytes}) RingBuffer{bufbytes}}; RingBufferPtr rb{new (FamCount{bufbytes}) RingBuffer{bufbytes}};