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

Commit 807ae39c authored by Arthur Hung's avatar Arthur Hung Committed by Android (Google) Code Review
Browse files

Merge "Fix potential synchronized race between SF and InputFlinger" into sc-dev

parents 316bdbd6 2274a314
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