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

Commit e40864ed authored by jiabin's avatar jiabin
Browse files

Stop command thread only for the first close request.

When there are multiple close stream request coming in simultaneously,
the aaudio service should only stop the command thread once.

Bug: 320114151
Test: atest test_multiple_close_simultaneously
Change-Id: Ib6e8474b5d126fb0114c0adbcb7e0207f7bb1dac
parent a8ea0380
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -49,12 +49,6 @@ enum {
};
typedef int32_t aaudio_policy_t;

// Internal error codes. Only used by the framework.
enum {
    AAUDIO_INTERNAL_ERROR_BASE = -1000,
    AAUDIO_ERROR_STANDBY,
};

/**
 * Control whether AAudioStreamBuilder_openStream() will use the new MMAP data path
 * or the older "Legacy" data path.
+8 −0
Original line number Diff line number Diff line
@@ -22,6 +22,14 @@

namespace aaudio {

// Internal error codes. Only used by the framework.
enum {
    AAUDIO_INTERNAL_ERROR_BASE = -1000,
    AAUDIO_ERROR_STANDBY,
    AAUDIO_ERROR_ALREADY_CLOSED,

};

aaudio_policy_t AudioGlobal_getMMapPolicy();
aaudio_result_t AudioGlobal_setMMapPolicy(aaudio_policy_t policy);

+18 −13
Original line number Diff line number Diff line
@@ -75,11 +75,7 @@ AAudioServiceStreamBase::~AAudioServiceStreamBase() {
                        this, getState());

    // Stop the command thread before destroying.
    if (mThreadEnabled) {
        mThreadEnabled = false;
        mCommandQueue.stopWaiting();
        mCommandThread.stop();
    }
    stopCommandThread();
}

std::string AAudioServiceStreamBase::dumpHeader() {
@@ -194,26 +190,27 @@ aaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest

error:
    closeAndClear();
    mThreadEnabled = false;
    mCommandQueue.stopWaiting();
    mCommandThread.stop();
    stopCommandThread();
    return result;
}

aaudio_result_t AAudioServiceStreamBase::close() {
    aaudio_result_t result = sendCommand(CLOSE, nullptr, true /*waitForReply*/, TIMEOUT_NANOS);
    if (result == AAUDIO_ERROR_ALREADY_CLOSED) {
        // AAUDIO_ERROR_ALREADY_CLOSED is not a really error but just indicate the stream has
        // already been closed. In that case, there is no need to close the stream once more.
        ALOGD("The stream(%d) is already closed", mHandle);
        return AAUDIO_OK;
    }

    // Stop the command thread as the stream is closed.
    mThreadEnabled = false;
    mCommandQueue.stopWaiting();
    mCommandThread.stop();
    stopCommandThread();

    return result;
}

aaudio_result_t AAudioServiceStreamBase::close_l() {
    if (getState() == AAUDIO_STREAM_STATE_CLOSED) {
        return AAUDIO_OK;
        return AAUDIO_ERROR_ALREADY_CLOSED;
    }

    // This will stop the stream, just in case it was not already stopped.
@@ -766,3 +763,11 @@ aaudio_result_t AAudioServiceStreamBase::closeAndClear() {
        .record();
    return result;
}

void AAudioServiceStreamBase::stopCommandThread() {
    bool threadEnabled = true;
    if (mThreadEnabled.compare_exchange_strong(threadEnabled, false)) {
        mCommandQueue.stopWaiting();
        mCommandThread.stop();
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -360,7 +360,7 @@ protected:
        EXIT_STANDBY,
    };
    AAudioThread            mCommandThread;
    std::atomic<bool>       mThreadEnabled{false};
    std::atomic_bool        mThreadEnabled{false};
    AAudioCommandQueue      mCommandQueue;

    int32_t                 mFramesPerBurst = 0;
@@ -400,6 +400,8 @@ private:
                                bool waitForReply = false,
                                int64_t timeoutNanos = 0);

    void stopCommandThread();

    aaudio_result_t closeAndClear();

    /**