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

Commit 5a36f93b authored by youfa.song's avatar youfa.song
Browse files

libaudioclient: fix AudioTrack blocking write after underrun



After checking that the ring buffer is full and before waiting for more buffer space,
there's a window where AudioFlinger may disable the track due to an underrun.
If this occurs, the client track will never wake up because it awaits buffer space
that will never become available.
This commit addresses the issue by ensuring the client track handles this scenario properly,
preventing a potential hang.

Change-Id: I4b9575c7a70ef7d5ad2158c9e27cd9259ab7cfe6
Signed-off-by: default avataryoufa.song <vsyfar@gmail.com>
parent aa1a64aa
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -310,8 +310,16 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques
            ts = NULL;
            break;
        }

        int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
        if (!(old & CBLK_FUTEX_WAKE)) {

        // Check inactive to prevent waiting if the track has been disabled due to underrun
        // (or invalidated).  The subsequent call to obtainBufer will return NOT_ENOUGH_DATA
        // (or DEAD_OBJECT) and restart (or restore) the track.
        const int32_t current_flags = android_atomic_acquire_load(&cblk->mFlags);
        const bool inactive = current_flags & (CBLK_INVALID | CBLK_DISABLED);

        if (!(old & CBLK_FUTEX_WAKE) && !inactive) {
            if (measure && !beforeIsValid) {
                clock_gettime(CLOCK_MONOTONIC, &before);
                beforeIsValid = true;