Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82a69ea8 authored by zunkyu.lee's avatar zunkyu.lee Committed by Glenn Kasten
Browse files

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
parent ca7b4bc4
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -307,6 +307,7 @@ void ClientProxy::binderDied()
{
{
    audio_track_cblk_t* cblk = mCblk;
    audio_track_cblk_t* cblk = mCblk;
    if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) {
    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
        // 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,
        (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
                1);
                1);
@@ -317,6 +318,7 @@ void ClientProxy::interrupt()
{
{
    audio_track_cblk_t* cblk = mCblk;
    audio_track_cblk_t* cblk = mCblk;
    if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) {
    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,
        (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
                1);
                1);
    }
    }