diff --git a/src/test/app/PathMPT_test.cpp b/src/test/app/PathMPT_test.cpp index 234c351dce..f6339d9676 100644 --- a/src/test/app/PathMPT_test.cpp +++ b/src/test/app/PathMPT_test.cpp @@ -135,6 +135,9 @@ public: numSrc.reserve(RPC::Tuning::kMaxSrcCur); for (std::uint8_t i = 0; i < RPC::Tuning::kMaxSrcCur; ++i) numSrc.push_back(makeMptID(i, bob)); + // Safe capture: the test blocks on g.waitFor() until the coroutine + // completes, so the captured locals outlive the coroutine. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) app.getJobQueue().postCoroTask(JtClient, "RPC-Client", [&](auto) -> CoroTask { context.params = xrpl::test::detail::rpf(alice, bob, usd, numSrc); RPC::doCommand(context, result); @@ -146,6 +149,9 @@ public: // Test more than RPC::Tuning::max_src_cur source currencies. numSrc.push_back(makeMptID(RPC::Tuning::kMaxSrcCur, bob)); + // Safe capture: the test blocks on g.waitFor() until the coroutine + // completes, so the captured locals outlive the coroutine. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) app.getJobQueue().postCoroTask(JtClient, "RPC-Client", [&](auto) -> CoroTask { context.params = xrpl::test::detail::rpf(alice, bob, usd, numSrc); RPC::doCommand(context, result); @@ -162,6 +168,9 @@ public: auto curm = MPTTester({.env = env, .issuer = alice, .holders = {bob}}); numSrc.push_back(curm.issuanceID()); } + // Safe capture: the test blocks on g.waitFor() until the coroutine + // completes, so the captured locals outlive the coroutine. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) app.getJobQueue().postCoroTask(JtClient, "RPC-Client", [&](auto) -> CoroTask { context.params = xrpl::test::detail::rpf(alice, bob, usd, {}); RPC::doCommand(context, result); @@ -173,6 +182,9 @@ public: // Test more than RPC::Tuning::max_auto_src_cur source currencies. auto curm = MPTTester({.env = env, .issuer = alice, .holders = {bob}}); + // Safe capture: the test blocks on g.waitFor() until the coroutine + // completes, so the captured locals outlive the coroutine. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) app.getJobQueue().postCoroTask(JtClient, "RPC-Client", [&](auto) -> CoroTask { context.params = xrpl::test::detail::rpf(alice, bob, usd, {}); RPC::doCommand(context, result); diff --git a/src/xrpld/app/main/GRPCServer.cpp b/src/xrpld/app/main/GRPCServer.cpp index 70ea6c56a1..5dc3e905a5 100644 --- a/src/xrpld/app/main/GRPCServer.cpp +++ b/src/xrpld/app/main/GRPCServer.cpp @@ -148,7 +148,12 @@ GRPCServerImpl::CallData::process() // is returned as a tag in handleRpcs(), after sending the response finished_ = true; auto runner = app_.getJobQueue().postCoroTask( - JobType::JtRpc, "gRPC-Client", [thisShared](auto) -> CoroTask { + JobType::JtRpc, + "gRPC-Client", + // Safe capture: postCoroTask heap-allocates the lambda (FuncStore) + // and thisShared keeps the CallData alive until the coroutine ends. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) + [thisShared](auto) -> CoroTask { thisShared->processRequest(); co_return; }); diff --git a/src/xrpld/app/main/GRPCServer.h b/src/xrpld/app/main/GRPCServer.h index bd9aae8b85..2ff338cb1a 100644 --- a/src/xrpld/app/main/GRPCServer.h +++ b/src/xrpld/app/main/GRPCServer.h @@ -6,7 +6,6 @@ #include #include -#include #include #include #include diff --git a/src/xrpld/rpc/Context.h b/src/xrpld/rpc/Context.h index 3df65398a0..ade96542f6 100644 --- a/src/xrpld/rpc/Context.h +++ b/src/xrpld/rpc/Context.h @@ -8,7 +8,6 @@ #include #include -#include #include namespace xrpl { @@ -31,7 +30,7 @@ struct Context LedgerMaster& ledgerMaster; Resource::Consumer& consumer; Role role; - InfoSub::pointer infoSub{}; + InfoSub::pointer infoSub; unsigned int apiVersion; }; diff --git a/src/xrpld/rpc/ServerHandler.h b/src/xrpld/rpc/ServerHandler.h index 3eba05abcb..287c9b3055 100644 --- a/src/xrpld/rpc/ServerHandler.h +++ b/src/xrpld/rpc/ServerHandler.h @@ -194,7 +194,7 @@ private: Port const& port, std::string const& request, beast::IP::Endpoint const& remoteIPAddress, - Output&&, + Output const&, std::string_view forwardedFor, std::string_view user); diff --git a/src/xrpld/rpc/detail/ServerHandler.cpp b/src/xrpld/rpc/detail/ServerHandler.cpp index 43aeaceab2..c697c768a1 100644 --- a/src/xrpld/rpc/detail/ServerHandler.cpp +++ b/src/xrpld/rpc/detail/ServerHandler.cpp @@ -319,7 +319,13 @@ ServerHandler::onRequest(Session& session) std::shared_ptr const detachedSession = session.detach(); auto const postResult = jobQueue_.postCoroTask( - JtClientRpc, "RPC-Client", [this, detachedSession](auto) -> CoroTask { + JtClientRpc, + "RPC-Client", + // Safe capture: postCoroTask heap-allocates the lambda (FuncStore), + // detachedSession is captured by value, and this (the ServerHandler) + // outlives the JobQueue jobs. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) + [this, detachedSession](auto) -> CoroTask { try { processSession(detachedSession); @@ -367,6 +373,10 @@ ServerHandler::onWSMessage( auto const postResult = jobQueue_.postCoroTask( JtClientWebsocket, "WS-Client", + // Safe capture: postCoroTask heap-allocates the lambda (FuncStore), + // session and jv are captured by value, and this (the ServerHandler) + // outlives the JobQueue jobs. + // NOLINTNEXTLINE(cppcoreguidelines-avoid-capturing-lambda-coroutines) [this, session, jv = std::move(jv)](auto) -> CoroTask { try { @@ -612,7 +622,7 @@ ServerHandler::processRequest( Port const& port, std::string const& request, beast::IP::Endpoint const& remoteIPAddress, - Output&& output, + Output const& output, std::string_view forwardedFor, std::string_view user) { diff --git a/src/xrpld/rpc/handlers/orderbook/RipplePathFind.cpp b/src/xrpld/rpc/handlers/orderbook/RipplePathFind.cpp index 0dc4bdb926..a892cd869b 100644 --- a/src/xrpld/rpc/handlers/orderbook/RipplePathFind.cpp +++ b/src/xrpld/rpc/handlers/orderbook/RipplePathFind.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -85,7 +84,7 @@ doRipplePathFind(RPC::JsonContext& context) request, [state]() { { - std::lock_guard const lk(state->mtx); + std::scoped_lock const lk(state->mtx); state->done = true; } state->cv.notify_one();