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

Commit ae58f439 authored by Steven Moreland's avatar Steven Moreland
Browse files

libbinder: RPC fix 'Die' race

Before this change, what would normally happen is this:

1. we connect to a server and make some calls
2. we make the Die call which returns DEAD_OBJECT
3. we send decStrong on the root binder
4. decStrong on the root binder returns a failure
5. rpcSend calls shutdownAndWait, to terminate the session

However, we actually know we should terminate the session at (2) (any
failure here indicates a serious problem). This was causing a flake
because sometimes (being a send only w/ no read), (4) would return a
success. So, we wouldn't shutdown the session.

Fixes: 200167417
Test: binderRpcTest --gtest_filter="*Die*" (on Pixel 3, repeatedly)
Test: binderRpcTest (on Pixel 3, w/ and w/o this change several times
    - this does not introduce additional failures, and failures
    are tracked by b/200173589)
Change-Id: I4894c2dd710b8cda59883c91e002b52ad67b1e26
parent c591b475
Loading
Loading
Loading
Loading
+5 −3
Original line number Original line Diff line number Diff line
@@ -323,6 +323,7 @@ status_t RpcState::rpcRec(const sp<RpcSession::RpcConnection>& connection,
        status != OK) {
        status != OK) {
        LOG_RPC_DETAIL("Failed to read %s (%zu bytes) on RpcTransport %p, error: %s", what, size,
        LOG_RPC_DETAIL("Failed to read %s (%zu bytes) on RpcTransport %p, error: %s", what, size,
                       connection->rpcTransport.get(), statusToString(status).c_str());
                       connection->rpcTransport.get(), statusToString(status).c_str());
        (void)session->shutdownAndWait(false);
        return status;
        return status;
    }
    }


@@ -531,8 +532,8 @@ status_t RpcState::waitForReply(const sp<RpcSession::RpcConnection>& connection,
                                const sp<RpcSession>& session, Parcel* reply) {
                                const sp<RpcSession>& session, Parcel* reply) {
    RpcWireHeader command;
    RpcWireHeader command;
    while (true) {
    while (true) {
        if (status_t status =
        if (status_t status = rpcRec(connection, session, "command header (for reply)", &command,
                    rpcRec(connection, session, "command header", &command, sizeof(command));
                                     sizeof(command));
            status != OK)
            status != OK)
            return status;
            return status;


@@ -601,7 +602,8 @@ status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& con
    LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get());
    LOG_RPC_DETAIL("getAndExecuteCommand on RpcTransport %p", connection->rpcTransport.get());


    RpcWireHeader command;
    RpcWireHeader command;
    if (status_t status = rpcRec(connection, session, "command header", &command, sizeof(command));
    if (status_t status = rpcRec(connection, session, "command header (for server)", &command,
                                 sizeof(command));
        status != OK)
        status != OK)
        return status;
        return status;