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

Commit 1c204929 authored by haobo10173529's avatar haobo10173529 Committed by Andy Hung
Browse files

AudioFlinger: Fix deadlock when createEffect_l fails.

The handle.clear() will cause deadlock if init of EffectHandle
failed due to NO_MEMORY in createEffect_l.

Test: Monkey test, Instrumented test.
Bug: 75031792
Change-Id: Ie0f38d76a66aeafe26903dda6690d1fe7fca4464
parent fa87fc3b
Loading
Loading
Loading
Loading
+9 −4
Original line number Original line Diff line number Diff line
@@ -3041,16 +3041,21 @@ sp<IEffect> AudioFlinger::createEffect(
        bool pinned = (sessionId > AUDIO_SESSION_OUTPUT_MIX) && isSessionAcquired_l(sessionId);
        bool pinned = (sessionId > AUDIO_SESSION_OUTPUT_MIX) && isSessionAcquired_l(sessionId);
        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
        handle = thread->createEffect_l(client, effectClient, priority, sessionId,
                &desc, enabled, &lStatus, pinned);
                &desc, enabled, &lStatus, pinned);
        if (handle != 0 && id != NULL) {
        if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
            *id = handle->id();
        }
        if (handle == 0) {
            // remove local strong reference to Client with mClientLock held
            // remove local strong reference to Client with mClientLock held
            Mutex::Autolock _cl(mClientLock);
            Mutex::Autolock _cl(mClientLock);
            client.clear();
            client.clear();
        } else {
            // handle must be valid here, but check again to be safe.
            if (handle.get() != nullptr && id != nullptr) *id = handle->id();
        }
        }
    }
    }


    if (lStatus != NO_ERROR && lStatus != ALREADY_EXISTS) {
        // handle must be cleared outside lock.
        handle.clear();
    }

Exit:
Exit:
    *status = lStatus;
    *status = lStatus;
    return handle;
    return handle;
+1 −1
Original line number Original line Diff line number Diff line
@@ -1354,7 +1354,7 @@ Exit:
        if (chainCreated) {
        if (chainCreated) {
            removeEffectChain_l(chain);
            removeEffectChain_l(chain);
        }
        }
        handle.clear();
        // handle must be cleared by caller to avoid deadlock.
    }
    }


    *status = lStatus;
    *status = lStatus;