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

Commit d92e5b0a 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: I6ef74a487e3033e481ffe68279af4feed0d14444
parents c57d1a9e 807ae39c
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -3105,7 +3105,7 @@ void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config,


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


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


    mTransactionQueue.emplace(state);
    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();
    for (auto it = mTransactionCommittedSignals.begin();
         it != mTransactionCommittedSignals.end();) {
         it != mTransactionCommittedSignals.end();) {
        if ((*it)->countDown() == 0) {
        if ((*it)->countDown(flag)) {
            it = mTransactionCommittedSignals.erase(it);
            it = mTransactionCommittedSignals.erase(it);
        } else {
        } else {
            it++;
            it++;
@@ -6175,7 +6177,7 @@ status_t SurfaceFlinger::renderScreenImplLocked(


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


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


    class CountDownLatch {
    class CountDownLatch {
    public:
    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);
            std::unique_lock<std::mutex> lock(mMutex);
            if (mCount == 0) {
            if (mFlags == 0) {
                return 0;
                return true;
            }
            }
            if (--mCount == 0) {
            mFlags &= ~flag;
            if (mFlags == 0) {
                mCountDownComplete.notify_all();
                mCountDownComplete.notify_all();
                return true;
            }
            }
            return mCount;
            return false;
        }
        }


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


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


    /*
    /*
     * Generic Layer Metadata
     * Generic Layer Metadata