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

Commit 0fafdb81 authored by Marissa Wall's avatar Marissa Wall Committed by android-build-merger
Browse files

Merge "transactions: fix mutex deadlock on layer death" into qt-dev

am: 1db00e0a

Change-Id: I009654a8678a1d0c36474c7e0856cbde384d7b3d
parents 113db105 1db00e0a
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ void TransactionCompletedThread::threadMain() {

    while (mKeepRunning) {
        mConditionVariable.wait(mMutex);
        std::vector<ListenerStats> completedListenerStats;

        // For each listener
        auto completedTransactionsItr = mCompletedTransactions.begin();
@@ -264,11 +265,27 @@ void TransactionCompletedThread::threadMain() {
            } else {
                completedTransactionsItr++;
            }

            completedListenerStats.push_back(std::move(listenerStats));
        }

        if (mPresentFence) {
            mPresentFence.clear();
        }

        // If everyone else has dropped their reference to a layer and its listener is dead,
        // we are about to cause the layer to be deleted. If this happens at the wrong time and
        // we are holding mMutex, we will cause a deadlock.
        //
        // The deadlock happens because this thread is holding on to mMutex and when we delete
        // the layer, it grabs SF's mStateLock. A different SF binder thread grabs mStateLock,
        // then call's TransactionCompletedThread::run() which tries to grab mMutex.
        //
        // To avoid this deadlock, we need to unlock mMutex when dropping our last reference to
        // to the layer.
        mMutex.unlock();
        completedListenerStats.clear();
        mMutex.lock();
    }
}