summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-03-17 09:36:51 -0700
committerEric Laurent <elaurent@google.com>2011-03-18 08:56:45 -0700
commit33797ea64d067dfeaacbfd7ebe7f3383b73961b5 (patch)
tree03aad0239e15dbb12e56c29f4d886e72e111ee2f /services
parent00d48b9495265457dfb265e766296212b5447b0e (diff)
downloadframeworks_av-33797ea64d067dfeaacbfd7ebe7f3383b73961b5.zip
frameworks_av-33797ea64d067dfeaacbfd7ebe7f3383b73961b5.tar.gz
frameworks_av-33797ea64d067dfeaacbfd7ebe7f3383b73961b5.tar.bz2
Fix issue 4111672: AudioTrack control block flags
Make sure that all read/modify/write operations on the AudioTrack and AudioRecord control block flags field are protected by the control block's mutex. Also fix potential infinite loop in AudioTrack::write() if the written size is not a multiple of frame size. Change-Id: Ib3d557eb45dcc3abeb32c9aa56058e2873afee27
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp23
1 files changed, 14 insertions, 9 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2b08ab5..2702242 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1738,7 +1738,10 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
tracksToRemove->add(track);
// indicate to client process that the track was disabled because of underrun
- cblk->flags |= CBLK_DISABLED_ON;
+ {
+ AutoMutex _l(cblk->lock);
+ cblk->flags |= CBLK_DISABLED_ON;
+ }
} else if (mixerStatus != MIXER_TRACKS_READY) {
mixerStatus = MIXER_TRACKS_ENABLED;
}
@@ -1787,10 +1790,9 @@ void AudioFlinger::MixerThread::invalidateTracks(int streamType)
for (size_t i = 0; i < size; i++) {
sp<Track> t = mTracks[i];
if (t->type() == streamType) {
- t->mCblk->lock.lock();
+ AutoMutex _lcblk(t->mCblk->lock);
t->mCblk->flags |= CBLK_INVALID_ON;
t->mCblk->cv.signal();
- t->mCblk->lock.unlock();
}
}
}
@@ -2948,6 +2950,7 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mCblk->framesReady() >= mCblk->frameCount ||
(mCblk->flags & CBLK_FORCEREADY_MSK)) {
+ AutoMutex _l(mCblk->lock);
mFillingUpStatus = FS_FILLED;
mCblk->flags &= ~CBLK_FORCEREADY_MSK;
return true;
@@ -3063,19 +3066,18 @@ void AudioFlinger::PlaybackThread::Track::flush()
// STOPPED state
mState = STOPPED;
- mCblk->lock.lock();
// NOTE: reset() will reset cblk->user and cblk->server with
// the risk that at the same time, the AudioMixer is trying to read
// data. In this case, getNextBuffer() would return a NULL pointer
// as audio buffer => the AudioMixer code MUST always test that pointer
// returned by getNextBuffer() is not NULL!
reset();
- mCblk->lock.unlock();
}
}
void AudioFlinger::PlaybackThread::Track::reset()
{
+ AutoMutex _l(mCblk->lock);
// Do not reset twice to avoid discarding data written just after a flush and before
// the audioflinger thread detects the track is stopped.
if (!mResetDone) {
@@ -3209,10 +3211,13 @@ void AudioFlinger::RecordThread::RecordTrack::stop()
if (thread != 0) {
RecordThread *recordThread = (RecordThread *)thread.get();
recordThread->stop(this);
- TrackBase::reset();
- // Force overerrun condition to avoid false overrun callback until first data is
- // read from buffer
- mCblk->flags |= CBLK_UNDERRUN_ON;
+ {
+ AutoMutex _l(mCblk->lock);
+ TrackBase::reset();
+ // Force overerrun condition to avoid false overrun callback until first data is
+ // read from buffer
+ mCblk->flags |= CBLK_UNDERRUN_ON;
+ }
}
}