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

Commit 31bde7a0 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: RPC factor out BinderNode erase

In preparation for adding an invariant here.

Bug: 183140903
Test: binderRpcTest
Change-Id: I541f7c3e5bcb5ee049fabe34acb9784cfeed0d0c
parent 8617ad80
Loading
Loading
Loading
Loading
+14 −11
Original line number Diff line number Diff line
@@ -458,9 +458,8 @@ status_t RpcState::sendDecStrong(const base::unique_fd& fd, const RpcAddress& ad
                            addr.toString().c_str());

        it->second.timesRecd--;
        if (it->second.timesRecd == 0 && it->second.timesSent == 0) {
            mNodeForAddress.erase(it);
        }
        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
                            "Bad state. RpcState shouldn't own received binder");
    }

    RpcWireHeader cmd = {
@@ -799,22 +798,26 @@ status_t RpcState::processDecStrong(const base::unique_fd& fd, const sp<RpcSessi
    LOG_ALWAYS_FATAL_IF(it->second.sentRef == nullptr, "Inconsistent state, lost ref for %s",
                        addr.toString().c_str());

    sp<IBinder> tempHold;

    it->second.timesSent--;
    sp<IBinder> tempHold = tryEraseNode(it);
    _l.unlock();
    tempHold = nullptr; // destructor may make binder calls on this session

    return OK;
}

sp<IBinder> RpcState::tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it) {
    sp<IBinder> ref;

    if (it->second.timesSent == 0) {
        tempHold = it->second.sentRef;
        it->second.sentRef = nullptr;
        ref = std::move(it->second.sentRef);

        if (it->second.timesRecd == 0) {
            mNodeForAddress.erase(it);
        }
    }

    _l.unlock();
    tempHold = nullptr; // destructor may make binder calls on this session

    return OK;
    return ref;
}

} // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -195,6 +195,12 @@ private:
        // (no additional data specific to remote binders)
    };

    // checks if there is any reference left to a node and erases it. If erase
    // happens, and there is a strong reference to the binder kept by
    // binderNode, this returns that strong reference, so that it can be
    // dropped after any locks are removed.
    sp<IBinder> tryEraseNode(std::map<RpcAddress, BinderNode>::iterator& it);

    std::mutex mNodeMutex;
    bool mTerminated = false;
    // binders known by both sides of a session