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

Commit 0523f705 authored by Matthew Bouyack's avatar Matthew Bouyack Committed by Gerrit Code Review
Browse files

Merge "Track elapsed time for 'waitStreamEnd' timeout"

parents d621f14f 7fd95182
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -490,6 +490,8 @@ bool AudioTrackClientProxy::getStreamEndDone() const {
status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *requested)
{
    struct timespec total;          // total elapsed time spent waiting
    struct timespec before;
    bool beforeIsValid = false;
    total.tv_sec = 0;
    total.tv_nsec = 0;
    audio_track_cblk_t* cblk = mCblk;
@@ -570,17 +572,38 @@ status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *request
        }
        int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
        if (!(old & CBLK_FUTEX_WAKE)) {
            if (!beforeIsValid) {
                clock_gettime(CLOCK_MONOTONIC, &before);
                beforeIsValid = true;
            }
            errno = 0;
            (void) syscall(__NR_futex, &cblk->mFutex,
                    mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
            switch (errno) {
            status_t error = errno; // clock_gettime can affect errno
            {
                struct timespec after;
                clock_gettime(CLOCK_MONOTONIC, &after);
                total.tv_sec += after.tv_sec - before.tv_sec;
                // Use auto instead of long to avoid the google-runtime-int warning.
                auto deltaNs = after.tv_nsec - before.tv_nsec;
                if (deltaNs < 0) {
                    deltaNs += 1000000000;
                    total.tv_sec--;
                }
                if ((total.tv_nsec += deltaNs) >= 1000000000) {
                    total.tv_nsec -= 1000000000;
                    total.tv_sec++;
                }
                before = after;
            }
            switch (error) {
            case 0:            // normal wakeup by server, or by binderDied()
            case EWOULDBLOCK:  // benign race condition with server
            case EINTR:        // wait was interrupted by signal or other spurious wakeup
            case ETIMEDOUT:    // time-out expired
                break;
            default:
                status = errno;
                status = error;
                ALOGE("%s unexpected error %s", __func__, strerror(status));
                goto end;
            }