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

Commit dcec9035 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Simplify AudioTrack stream end and fix race

Bug: 10994052
Change-Id: Ib2e38e7a600bcffef8cbc68c1722e40fbbc7ea67
parent 5bc83fc3
Loading
Loading
Loading
Loading
+15 −17
Original line number Diff line number Diff line
@@ -1445,6 +1445,7 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
    }
    size_t misalignment = mProxy->getMisalignment();
    uint32_t sequence = mSequence;
    sp<AudioTrackClientProxy> proxy = mProxy;

    // These fields don't need to be cached, because they are assigned only by set():
    //     mTransfer, mCbf, mUserData, mFormat, mFrameSize, mFrameSizeAF, mFlags
@@ -1453,35 +1454,32 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
    mLock.unlock();

    if (waitStreamEnd) {
        AutoMutex lock(mLock);

        sp<AudioTrackClientProxy> proxy = mProxy;
        sp<IMemory> iMem = mCblkMemory;

        struct timespec timeout;
        timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
        timeout.tv_nsec = 0;

        mLock.unlock();
        status_t status = mProxy->waitStreamEndDone(&timeout);
        mLock.lock();
        status_t status = proxy->waitStreamEndDone(&timeout);
        switch (status) {
        case NO_ERROR:
        case DEAD_OBJECT:
        case TIMED_OUT:
            mLock.unlock();
            mCbf(EVENT_STREAM_END, mUserData, NULL);
            mLock.lock();
            if (mState == STATE_STOPPING) {
            {
                AutoMutex lock(mLock);
                // The previously assigned value of waitStreamEnd is no longer valid,
                // since the mutex has been unlocked and either the callback handler
                // or another thread could have re-started the AudioTrack during that time.
                waitStreamEnd = mState == STATE_STOPPING;
                if (waitStreamEnd) {
                    mState = STATE_STOPPED;
                if (status != DEAD_OBJECT) {
                }
            }
            if (waitStreamEnd && status != DEAD_OBJECT) {
               return NS_INACTIVE;
            }
            break;
        }
        return 0;
        default:
            return 0;
        }
    }

    // perform callbacks while unlocked