From 82a69ea8b090d57bff5e02774688b546a711bbb8 Mon Sep 17 00:00:00 2001 From: "zunkyu.lee" Date: Fri, 7 Nov 2014 15:47:32 +0900 Subject: 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 --- media/libmedia/AudioTrackShared.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'media/libmedia/AudioTrackShared.cpp') diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp index 4a783b3..ff24475 100644 --- a/media/libmedia/AudioTrackShared.cpp +++ b/media/libmedia/AudioTrackShared.cpp @@ -307,6 +307,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); @@ -317,6 +318,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); } -- cgit v1.1