diff options
author | zunkyu.lee <zunkyu.lee@lge.com> | 2014-11-07 15:47:32 +0900 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2014-12-08 15:46:00 -0800 |
commit | a78e10495c51d09f92db9c33d34dcc7cd7f28511 (patch) | |
tree | 6dc34a425be7c95946e0315878c5ab9b2d125c16 /media | |
parent | 1a9c3954a20800dda3d6d18048c7f0edc8c53e6a (diff) | |
download | frameworks_av-a78e10495c51d09f92db9c33d34dcc7cd7f28511.zip frameworks_av-a78e10495c51d09f92db9c33d34dcc7cd7f28511.tar.gz frameworks_av-a78e10495c51d09f92db9c33d34dcc7cd7f28511.tar.bz2 |
Prevent ANR when AudioTrack is paused or re-routed
If ClientProxy was interrupted by AudioTrack::pause() just before futex syscall() in obtainBuffer() was called,
It will not call releaseBuffer to wake up AudioTrackThread.
It puts the AudioTrackThread to sleep and then a deadlock occurs.
In this case, CBLK_INTERRUPT flags can't prevent a deadlock,
so this patch set mFutex to FUTEX_WAKE during interrupt() to avoid deadlock.
A similar problem could occur due to re-route or recovery after mediaserver death.
Bug: 18641665
Change-Id: I66fcae43af9a91eb55f6cdb52c644ee6c0999772
Diffstat (limited to 'media')
-rw-r--r-- | media/libmedia/AudioTrackShared.cpp | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index eec025e..52533f5 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -301,6 +301,7 @@ void ClientProxy::binderDied() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) { + android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); // it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); @@ -311,6 +312,7 @@ void ClientProxy::interrupt() { audio_track_cblk_t* cblk = mCblk; if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) { + android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex); (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1); } |