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

Commit e3ead6a3 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

am: 0fafdb81

Change-Id: I3ba75cf429725dda8bd380d7edca63b39ba656da
parents a7137b42 0fafdb81
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();
    }
}