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

Commit fbfc3a75 authored by Arthur Hung's avatar Arthur Hung Committed by Automerger Merge Worker
Browse files

Merge "Fix potential synchronized race between SF and InputFlinger" into sc-dev am: 807ae39c

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/14339452

Change-Id: Ib020ce186a95a78d7e1a407b9e1a7f40b0694d8c
parents 86c640c4 807ae39c
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -3105,7 +3105,7 @@ void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config,

void SurfaceFlinger::commitTransaction() {
    commitTransactionLocked();
    signalSynchronousTransactions();
    signalSynchronousTransactions(CountDownLatch::eSyncTransaction);
    mAnimTransactionPending = false;
}

@@ -3527,7 +3527,9 @@ void SurfaceFlinger::queueTransaction(TransactionState& state) {
    // Generate a CountDownLatch pending state if this is a synchronous transaction.
    if ((state.flags & eSynchronous) || state.inputWindowCommands.syncInputWindows) {
        state.transactionCommittedSignal = std::make_shared<CountDownLatch>(
                (state.inputWindowCommands.syncInputWindows ? 2 : 1));
                (state.inputWindowCommands.syncInputWindows
                         ? (CountDownLatch::eSyncInputWindows | CountDownLatch::eSyncTransaction)
                         : CountDownLatch::eSyncTransaction));
    }

    mTransactionQueue.emplace(state);
@@ -3552,10 +3554,10 @@ void SurfaceFlinger::waitForSynchronousTransaction(
    }
}

void SurfaceFlinger::signalSynchronousTransactions() {
void SurfaceFlinger::signalSynchronousTransactions(const uint32_t flag) {
    for (auto it = mTransactionCommittedSignals.begin();
         it != mTransactionCommittedSignals.end();) {
        if ((*it)->countDown() == 0) {
        if ((*it)->countDown(flag)) {
            it = mTransactionCommittedSignals.erase(it);
        } else {
            it++;
@@ -6175,7 +6177,7 @@ status_t SurfaceFlinger::renderScreenImplLocked(

void SurfaceFlinger::setInputWindowsFinished() {
    Mutex::Autolock _l(mStateLock);
    signalSynchronousTransactions();
    signalSynchronousTransactions(CountDownLatch::eSyncInputWindows);
}

// ---------------------------------------------------------------------------
+17 −10
Original line number Diff line number Diff line
@@ -467,24 +467,31 @@ private:

    class CountDownLatch {
    public:
        explicit CountDownLatch(int32_t count) : mCount(count) {}
        enum {
            eSyncTransaction = 1 << 0,
            eSyncInputWindows = 1 << 1,
        };
        explicit CountDownLatch(uint32_t flags) : mFlags(flags) {}

        int32_t countDown() {
        // True if there is no waiting condition after count down.
        bool countDown(uint32_t flag) {
            std::unique_lock<std::mutex> lock(mMutex);
            if (mCount == 0) {
                return 0;
            if (mFlags == 0) {
                return true;
            }
            if (--mCount == 0) {
            mFlags &= ~flag;
            if (mFlags == 0) {
                mCountDownComplete.notify_all();
                return true;
            }
            return mCount;
            return false;
        }

        // Return true if triggered.
        bool wait_until(const std::chrono::seconds& timeout) const {
            std::unique_lock<std::mutex> lock(mMutex);
            const auto untilTime = std::chrono::system_clock::now() + timeout;
            while (mCount != 0) {
            while (mFlags != 0) {
                // Conditional variables can be woken up sporadically, so we check count
                // to verify the wakeup was triggered by |countDown|.
                if (std::cv_status::timeout == mCountDownComplete.wait_until(lock, untilTime)) {
@@ -495,7 +502,7 @@ private:
        }

    private:
        int32_t mCount;
        uint32_t mFlags;
        mutable std::condition_variable mCountDownComplete;
        mutable std::mutex mMutex;
    };
@@ -1124,7 +1131,7 @@ private:
    // Add transaction to the Transaction Queue
    void queueTransaction(TransactionState& state) EXCLUDES(mQueueLock);
    void waitForSynchronousTransaction(const CountDownLatch& transactionCommittedSignal);
    void signalSynchronousTransactions();
    void signalSynchronousTransactions(const uint32_t flag);

    /*
     * Generic Layer Metadata