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

Commit 0f001eca authored by Glenn Kasten's avatar Glenn Kasten Committed by Automerger Merge Worker
Browse files

Merge "Fix race condition in AudioTrack::releaseBuffer()" am: 9242b79e am: 1baa323e

Change-Id: I274ea1fecbb343efa77788c80f4525a2fc05ba74
parents f1dec137 1baa323e
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -1665,7 +1665,6 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
{
    // previous and new IAudioTrack sequence numbers are used to detect track re-creation
    uint32_t oldSequence = 0;
    uint32_t newSequence;

    Proxy::Buffer buffer;
    status_t status = NO_ERROR;
@@ -1682,7 +1681,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
        {   // start of lock scope
            AutoMutex lock(mLock);

            newSequence = mSequence;
            uint32_t newSequence = mSequence;
            // did previous obtainBuffer() fail due to media server death or voluntary invalidation?
            if (status == DEAD_OBJECT) {
                // re-create track, unless someone else has already done so
@@ -1729,6 +1728,7 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, const struct timespec *re
    audioBuffer->frameCount = buffer.mFrameCount;
    audioBuffer->size = buffer.mFrameCount * mFrameSize;
    audioBuffer->raw = buffer.mRaw;
    audioBuffer->sequence = oldSequence;
    if (nonContig != NULL) {
        *nonContig = buffer.mNonContig;
    }
@@ -1752,6 +1752,12 @@ void AudioTrack::releaseBuffer(const Buffer* audioBuffer)
    buffer.mRaw = audioBuffer->raw;

    AutoMutex lock(mLock);
    if (audioBuffer->sequence != mSequence) {
        // This Buffer came from a different IAudioTrack instance, so ignore the releaseBuffer
        ALOGD("%s is no-op due to IAudioTrack sequence mismatch %u != %u",
                __func__, audioBuffer->sequence, mSequence);
        return;
    }
    mReleased += stepCount;
    mInUnderrun = false;
    mProxy->releaseBuffer(&buffer);
+8 −0
Original line number Diff line number Diff line
@@ -107,6 +107,11 @@ public:
            int16_t*    i16;      // signed 16-bit
            int8_t*     i8;       // unsigned 8-bit, offset by 0x80
        };                        // input to obtainBuffer(): unused, output: pointer to buffer

        uint32_t    sequence;       // IAudioTrack instance sequence number, as of obtainBuffer().
                                    // It is set by obtainBuffer() and confirmed by releaseBuffer().
                                    // Not "user-serviceable".
                                    // TODO Consider sp<IMemory> instead, or in addition to this.
    };

    /* As a convenience, if a callback is supplied, a handler thread
@@ -692,14 +697,17 @@ public:
     *  frameCount  number of [empty slots for] frames requested
     *  size        ignored
     *  raw         ignored
     *  sequence    ignored
     * After error return:
     *  frameCount  0
     *  size        0
     *  raw         undefined
     *  sequence    undefined
     * After successful return:
     *  frameCount  actual number of [empty slots for] frames available, <= number requested
     *  size        actual number of bytes available
     *  raw         pointer to the buffer
     *  sequence    IAudioTrack instance sequence number, as of obtainBuffer()
     */
            status_t    obtainBuffer(Buffer* audioBuffer, int32_t waitCount,
                                size_t *nonContig = NULL);