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

Commit 3bf4a472 authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge changes I3320d992,I655cf2c2 am: c8370a9c am: 5a52bcc7

parents 5afb1268 5a52bcc7
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -191,6 +191,7 @@ cc_defaults {
        "google-*",
        "google-*",
        "misc-*",
        "misc-*",
        "performance*",
        "performance*",
        "-performance-move-const-arg", // b/273486801
        "portability*",
        "portability*",
    ],
    ],
}
}
+31 −7
Original line number Original line Diff line number Diff line
@@ -262,8 +262,10 @@ void RpcState::dump() {
}
}


void RpcState::clear() {
void RpcState::clear() {
    RpcMutexUniqueLock _l(mNodeMutex);
    return clear(RpcMutexUniqueLock(mNodeMutex));
}


void RpcState::clear(RpcMutexUniqueLock nodeLock) {
    if (mTerminated) {
    if (mTerminated) {
        LOG_ALWAYS_FATAL_IF(!mNodeForAddress.empty(),
        LOG_ALWAYS_FATAL_IF(!mNodeForAddress.empty(),
                            "New state should be impossible after terminating!");
                            "New state should be impossible after terminating!");
@@ -292,7 +294,7 @@ void RpcState::clear() {
    auto temp = std::move(mNodeForAddress);
    auto temp = std::move(mNodeForAddress);
    mNodeForAddress.clear(); // RpcState isn't reusable, but for future/explicit
    mNodeForAddress.clear(); // RpcState isn't reusable, but for future/explicit


    _l.unlock();
    nodeLock.unlock();
    temp.clear(); // explicit
    temp.clear(); // explicit
}
}


@@ -704,7 +706,7 @@ status_t RpcState::sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& co
    };
    };


    {
    {
        RpcMutexLockGuard _l(mNodeMutex);
        RpcMutexUniqueLock _l(mNodeMutex);
        if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
        if (mTerminated) return DEAD_OBJECT; // avoid fatal only, otherwise races
        auto it = mNodeForAddress.find(addr);
        auto it = mNodeForAddress.find(addr);
        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(),
        LOG_ALWAYS_FATAL_IF(it == mNodeForAddress.end(),
@@ -720,8 +722,9 @@ status_t RpcState::sendDecStrongToTarget(const sp<RpcSession::RpcConnection>& co
        body.amount = it->second.timesRecd - target;
        body.amount = it->second.timesRecd - target;
        it->second.timesRecd = target;
        it->second.timesRecd = target;


        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(it),
        LOG_ALWAYS_FATAL_IF(nullptr != tryEraseNode(session, std::move(_l), it),
                            "Bad state. RpcState shouldn't own received binder");
                            "Bad state. RpcState shouldn't own received binder");
        // LOCK ALREADY RELEASED
    }
    }


    RpcWireHeader cmd = {
    RpcWireHeader cmd = {
@@ -1164,8 +1167,8 @@ status_t RpcState::processDecStrong(const sp<RpcSession::RpcConnection>& connect
                   it->second.timesSent);
                   it->second.timesSent);


    it->second.timesSent -= body.amount;
    it->second.timesSent -= body.amount;
    sp<IBinder> tempHold = tryEraseNode(it);
    sp<IBinder> tempHold = tryEraseNode(session, std::move(_l), it);
    _l.unlock();
    // LOCK ALREADY RELEASED
    tempHold = nullptr; // destructor may make binder calls on this session
    tempHold = nullptr; // destructor may make binder calls on this session


    return OK;
    return OK;
@@ -1229,7 +1232,10 @@ status_t RpcState::validateParcel(const sp<RpcSession>& session, const Parcel& p
    return OK;
    return OK;
}
}


sp<IBinder> RpcState::tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it) {
sp<IBinder> RpcState::tryEraseNode(const sp<RpcSession>& session, RpcMutexUniqueLock nodeLock,
                                   std::map<uint64_t, BinderNode>::iterator& it) {
    bool shouldShutdown = false;

    sp<IBinder> ref;
    sp<IBinder> ref;


    if (it->second.timesSent == 0) {
    if (it->second.timesSent == 0) {
@@ -1239,8 +1245,26 @@ sp<IBinder> RpcState::tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it)
            LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
            LOG_ALWAYS_FATAL_IF(!it->second.asyncTodo.empty(),
                                "Can't delete binder w/ pending async transactions");
                                "Can't delete binder w/ pending async transactions");
            mNodeForAddress.erase(it);
            mNodeForAddress.erase(it);

            if (mNodeForAddress.size() == 0) {
                shouldShutdown = true;
            }
            }
        }
        }
    }

    // If we shutdown, prevent RpcState from being re-used. This prevents another
    // thread from getting the root object again.
    if (shouldShutdown) {
        clear(std::move(nodeLock));
    } else {
        nodeLock.unlock(); // explicit
    }
    // LOCK IS RELEASED

    if (shouldShutdown) {
        ALOGI("RpcState has no binders left, so triggering shutdown...");
        (void)session->shutdownAndWait(false);
    }


    return ref;
    return ref;
}
}
+15 −5
Original line number Original line Diff line number Diff line
@@ -168,6 +168,7 @@ public:
    void clear();
    void clear();


private:
private:
    void clear(RpcMutexUniqueLock nodeLock);
    void dumpLocked();
    void dumpLocked();


    // Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
    // Alternative to std::vector<uint8_t> that doesn't abort on allocation failure and caps
@@ -268,11 +269,20 @@ private:
        std::string toString() const;
        std::string toString() const;
    };
    };


    // checks if there is any reference left to a node and erases it. If erase
    // Checks if there is any reference left to a node and erases it. If this
    // happens, and there is a strong reference to the binder kept by
    // is the last node, shuts down the session.
    // binderNode, this returns that strong reference, so that it can be
    //
    // dropped after any locks are removed.
    // Node lock is passed here for convenience, so that we can release it
    sp<IBinder> tryEraseNode(std::map<uint64_t, BinderNode>::iterator& it);
    // and terminate the session, but we could leave it up to the caller
    // by returning a continuation if we needed to erase multiple specific
    // nodes. It may be tempting to allow the client to keep on holding the
    // lock and instead just return whether or not we should shutdown, but
    // this introduces the posssibility that another thread calls
    // getRootBinder and thinks it is valid, rather than immediately getting
    // an error.
    sp<IBinder> tryEraseNode(const sp<RpcSession>& session, RpcMutexUniqueLock nodeLock,
                             std::map<uint64_t, BinderNode>::iterator& it);

    // true - success
    // true - success
    // false - session shutdown, halt
    // false - session shutdown, halt
    [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node);
    [[nodiscard]] bool nodeProgressAsyncNumber(BinderNode* node);
+3 −0
Original line number Original line Diff line number Diff line
@@ -51,6 +51,9 @@ constexpr uint32_t RPC_WIRE_PROTOCOL_VERSION_RPC_HEADER_FEATURE_EXPLICIT_PARCEL_
 * This represents a session (group of connections) between a client
 * This represents a session (group of connections) between a client
 * and a server. Multiple connections are needed for multiple parallel "binder"
 * and a server. Multiple connections are needed for multiple parallel "binder"
 * calls which may also have nested calls.
 * calls which may also have nested calls.
 *
 * Once a binder exists in the session, if all references to all binders are dropped,
 * the session shuts down.
 */
 */
class RpcSession final : public virtual RefBase {
class RpcSession final : public virtual RefBase {
public:
public:
+6 −2
Original line number Original line Diff line number Diff line
@@ -102,9 +102,11 @@ std::unique_ptr<RpcTransportCtxFactory> makeFactoryTls() {
}
}


static sp<RpcSession> gSession = RpcSession::make();
static sp<RpcSession> gSession = RpcSession::make();
static sp<IBinder> gRpcBinder;
// Certificate validation happens during handshake and does not affect the result of benchmarks.
// Certificate validation happens during handshake and does not affect the result of benchmarks.
// Skip certificate validation to simplify the setup process.
// Skip certificate validation to simplify the setup process.
static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
static sp<RpcSession> gSessionTls = RpcSession::make(makeFactoryTls());
static sp<IBinder> gRpcTlsBinder;
#ifdef __BIONIC__
#ifdef __BIONIC__
static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
static const String16 kKernelBinderInstance = String16(u"binderRpcBenchmark-control");
static sp<IBinder> gKernelBinder;
static sp<IBinder> gKernelBinder;
@@ -118,9 +120,9 @@ static sp<IBinder> getBinderForOptions(benchmark::State& state) {
            return gKernelBinder;
            return gKernelBinder;
#endif
#endif
        case RPC:
        case RPC:
            return gSession->getRootObject();
            return gRpcBinder;
        case RPC_TLS:
        case RPC_TLS:
            return gSessionTls->getRootObject();
            return gRpcTlsBinder;
        default:
        default:
            LOG(FATAL) << "Unknown transport value: " << transport;
            LOG(FATAL) << "Unknown transport value: " << transport;
            return nullptr;
            return nullptr;
@@ -254,11 +256,13 @@ int main(int argc, char** argv) {
    (void)unlink(addr.c_str());
    (void)unlink(addr.c_str());
    forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
    forkRpcServer(addr.c_str(), RpcServer::make(RpcTransportCtxFactoryRaw::make()));
    setupClient(gSession, addr.c_str());
    setupClient(gSession, addr.c_str());
    gRpcBinder = gSession->getRootObject();


    std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
    std::string tlsAddr = tmp + "/binderRpcTlsBenchmark";
    (void)unlink(tlsAddr.c_str());
    (void)unlink(tlsAddr.c_str());
    forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
    forkRpcServer(tlsAddr.c_str(), RpcServer::make(makeFactoryTls()));
    setupClient(gSessionTls, tlsAddr.c_str());
    setupClient(gSessionTls, tlsAddr.c_str());
    gRpcTlsBinder = gSessionTls->getRootObject();


    ::benchmark::RunSpecifiedBenchmarks();
    ::benchmark::RunSpecifiedBenchmarks();
    return 0;
    return 0;
Loading