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

Commit fce31b82 authored by Valerie Hau's avatar Valerie Hau
Browse files

Prevent onHandleDestroyed from being called w/ mStateLock

Now that we can apply transactions from the main thread, we can possibly
call onHandleDestroyed while mStatelock is held.  Add a copy outside the
lock boundaries to prevent this

Bug: 131421215
Test: build, boot, libsurfaceflinger_unittest
Change-Id: I0c7a3852d6706ec9df5467e5f4bd23061f11fa11
parent 8b30c364
Loading
Loading
Loading
Loading
+30 −22
Original line number Diff line number Diff line
@@ -3473,24 +3473,31 @@ uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags,
}

bool SurfaceFlinger::flushTransactionQueues() {
    Mutex::Autolock _l(mStateLock);
    // to prevent onHandleDestroyed from being called while the lock is held,
    // we must keep a copy of the transactions (specifically the composer
    // states) around outside the scope of the lock
    std::vector<const TransactionState> transactions;
    bool flushedATransaction = false;
    {
        Mutex::Autolock _l(mStateLock);

        auto it = mTransactionQueues.begin();
        while (it != mTransactionQueues.end()) {
            auto& [applyToken, transactionQueue] = *it;

            while (!transactionQueue.empty()) {
            const auto&
                    [states, displays, flags, desiredPresentTime, uncacheBuffer, listenerCallbacks,
                     postTime, privileged] = transactionQueue.front();
            if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
                const auto& transaction = transactionQueue.front();
                if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
                                                   transaction.states)) {
                    setTransactionFlags(eTransactionFlushNeeded);
                    break;
                }
            applyTransactionState(states, displays, flags, mPendingInputWindowCommands,
                                  desiredPresentTime, uncacheBuffer, listenerCallbacks, postTime,
                                  privileged, /*isMainThread*/ true);
                transactions.push_back(transaction);
                applyTransactionState(transaction.states, transaction.displays, transaction.flags,
                                      mPendingInputWindowCommands, transaction.desiredPresentTime,
                                      transaction.buffer, transaction.callback,
                                      transaction.postTime, transaction.privileged,
                                      /*isMainThread*/ true);
                transactionQueue.pop();
                flushedATransaction = true;
            }
@@ -3502,6 +3509,7 @@ bool SurfaceFlinger::flushTransactionQueues() {
                std::next(it, 1);
            }
        }
    }
    return flushedATransaction;
}