From f8c1a6f7ef515810356816b50bfe18af95f3ec32 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Tue, 10 Jan 2012 09:01:19 -0800 Subject: Fix race in AudioSystem::getInputBufferSize It was caching the recording parameters without a mutex. Change-Id: Ic4b9f621cbc080d224c2233cf3ca3454fc0f19bd --- media/libmedia/AudioSystem.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'media/libmedia/AudioSystem.cpp') diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp index f7f129c..caa3d30 100644 --- a/media/libmedia/AudioSystem.cpp +++ b/media/libmedia/AudioSystem.cpp @@ -38,7 +38,7 @@ audio_error_callback AudioSystem::gAudioErrorCallback = NULL; DefaultKeyedVector AudioSystem::gStreamOutputMap(0); DefaultKeyedVector AudioSystem::gOutputs(0); -// Cached values for recording queries +// Cached values for recording queries, all protected by gLock uint32_t AudioSystem::gPrevInSamplingRate = 16000; int AudioSystem::gPrevInFormat = AUDIO_FORMAT_PCM_16_BIT; int AudioSystem::gPrevInChannelCount = 1; @@ -301,22 +301,27 @@ status_t AudioSystem::getOutputLatency(uint32_t* latency, int streamType) status_t AudioSystem::getInputBufferSize(uint32_t sampleRate, int format, int channelCount, size_t* buffSize) { + gLock.lock(); // Do we have a stale gInBufferSize or are we requesting the input buffer size for new values - if ((gInBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) + size_t inBuffSize = gInBuffSize; + if ((inBuffSize == 0) || (sampleRate != gPrevInSamplingRate) || (format != gPrevInFormat) || (channelCount != gPrevInChannelCount)) { + gLock.unlock(); + const sp& af = AudioSystem::get_audio_flinger(); + if (af == 0) { + return PERMISSION_DENIED; + } + inBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); + gLock.lock(); // save the request params gPrevInSamplingRate = sampleRate; gPrevInFormat = format; gPrevInChannelCount = channelCount; - gInBuffSize = 0; - const sp& af = AudioSystem::get_audio_flinger(); - if (af == 0) { - return PERMISSION_DENIED; - } - gInBuffSize = af->getInputBufferSize(sampleRate, format, channelCount); + gInBuffSize = inBuffSize; } - *buffSize = gInBuffSize; + gLock.unlock(); + *buffSize = inBuffSize; return NO_ERROR; } -- cgit v1.1