Fix theoretical race using TrackBase::sampleRate()
In two places we assumed that TrackBase::sampleRate() would return the
same value when it is called twice in the same function. This is not
guaranteed; sampleRate() reads from the control block so the return
value could change. To fix this, only call sampleRate() once and cache
the return value to get a consistent value.
This was only a theoretical race. In MixerThread::prepareTracks_l()
it would have no bad effect. In TimedTrack::getNextBuffer() it could
cause a real problem, but we don't currently support dynamic sample rate
ratios for timed tracks.
Change-Id: I8e5c33f0121fc058d1e70c2ab5e9135397d3e0b7
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0773534..3b5727b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2427,7 +2427,7 @@
}
for (size_t i=0 ; i<count ; i++) {
- sp<Track> t = mActiveTracks[i].promote();
+ const sp<Track> t = mActiveTracks[i].promote();
if (t == 0) {
continue;
}
@@ -2597,11 +2597,12 @@
// hence the test on (mMixerStatus == MIXER_TRACKS_READY) meaning the track was mixed
// during last round
size_t desiredFrames;
- if (t->sampleRate() == mSampleRate) {
+ uint32_t sr = track->sampleRate();
+ if (sr == mSampleRate) {
desiredFrames = mNormalFrameCount;
} else {
// +1 for rounding and +1 for additional sample needed for interpolation
- desiredFrames = (mNormalFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
+ desiredFrames = (mNormalFrameCount * sr) / mSampleRate + 1 + 1;
// add frames already consumed but not yet released by the resampler
// because cblk->framesReady() will include these frames
desiredFrames += mAudioMixer->getUnreleasedFrames(track->name());