From 0c980bb2474126abdc86266c08ca9062a4447656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Wo=CC=81jcik?= <3044353+pwojcikdev@users.noreply.github.com> Date: Sun, 12 May 2024 21:53:06 +0200 Subject: [PATCH] Fix ipc server stop command --- nano/node/ipc/ipc_server.cpp | 15 +++++++++++++-- nano/node/ipc/ipc_server.hpp | 2 +- nano/rpc_test/rpc_context.cpp | 4 ++-- nano/rpc_test/rpc_context.hpp | 4 ++-- 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/nano/node/ipc/ipc_server.cpp b/nano/node/ipc/ipc_server.cpp index f68eb78b7..d642ad8db 100644 --- a/nano/node/ipc/ipc_server.cpp +++ b/nano/node/ipc/ipc_server.cpp @@ -277,9 +277,18 @@ public: auto body (std::string (reinterpret_cast (buffer.data ()), buffer.size ())); // Note that if the rpc action is async, the shared_ptr lifetime will be extended by the action handler - auto handler (std::make_shared (node, server.node_rpc_config, body, response_handler_l, [&server = server] () { - server.stop (); + auto handler (std::make_shared (node, server.node_rpc_config, body, response_handler_l, [server_w = server.weak_from_this ()] () { // TODO: Previously this was stopping node.io_ctx, which was wrong. Investigate what's going on here. Why isn't it using stop_callback passed externally? + // This is running on the IO thread, so attempting to directly stop the server will cause it to try joining itself. + // This RPC/IPC system is really badly designed... + std::thread ([server_w] () { + std::this_thread::sleep_for (std::chrono::seconds (1)); + if (auto server = server_w.lock ()) + { + server->stop (); + } + }) + .detach (); })); // For unsafe actions to be allowed, the unsafe encoding must be used AND the transport config must allow it handler->process_request (allow_unsafe && config_transport.allow_unsafe); @@ -600,6 +609,8 @@ nano::ipc::ipc_server::ipc_server (nano::node & node_a, nano::node_rpc_config co nano::ipc::ipc_server::~ipc_server () { node.logger.debug (nano::log::type::ipc_server, "Server stopped"); + + stop (); } void nano::ipc::ipc_server::stop () diff --git a/nano/node/ipc/ipc_server.hpp b/nano/node/ipc/ipc_server.hpp index 6b3b1d4cf..4c33cd01a 100644 --- a/nano/node/ipc/ipc_server.hpp +++ b/nano/node/ipc/ipc_server.hpp @@ -20,7 +20,7 @@ namespace ipc { class access; /** The IPC server accepts connections on one or more configured transports */ - class ipc_server final + class ipc_server final : public std::enable_shared_from_this { public: ipc_server (nano::node & node, nano::node_rpc_config const & node_rpc_config); diff --git a/nano/rpc_test/rpc_context.cpp b/nano/rpc_test/rpc_context.cpp index 31cadfdc4..fa0553da8 100644 --- a/nano/rpc_test/rpc_context.cpp +++ b/nano/rpc_test/rpc_context.cpp @@ -12,7 +12,7 @@ #include -nano::test::rpc_context::rpc_context (std::shared_ptr & rpc_a, std::unique_ptr & ipc_server_a, std::unique_ptr & ipc_rpc_processor_a, std::unique_ptr & node_rpc_config_a) +nano::test::rpc_context::rpc_context (std::shared_ptr & rpc_a, std::shared_ptr & ipc_server_a, std::unique_ptr & ipc_rpc_processor_a, std::unique_ptr & node_rpc_config_a) { rpc = std::move (rpc_a); ipc_server = std::move (ipc_server_a); @@ -45,7 +45,7 @@ bool nano::test::check_block_response_count (nano::test::system & system, rpc_co nano::test::rpc_context nano::test::add_rpc (nano::test::system & system, std::shared_ptr const & node_a) { auto node_rpc_config (std::make_unique ()); - auto ipc_server (std::make_unique (*node_a, *node_rpc_config)); + auto ipc_server (std::make_shared (*node_a, *node_rpc_config)); nano::rpc_config rpc_config (node_a->network_params.network, system.get_available_port (), true); const auto ipc_tcp_port = ipc_server->listening_tcp_port (); debug_assert (ipc_tcp_port.has_value ()); diff --git a/nano/rpc_test/rpc_context.hpp b/nano/rpc_test/rpc_context.hpp index 7c471f2ae..d313d3a2e 100644 --- a/nano/rpc_test/rpc_context.hpp +++ b/nano/rpc_test/rpc_context.hpp @@ -22,10 +22,10 @@ namespace test class rpc_context { public: - rpc_context (std::shared_ptr & rpc_a, std::unique_ptr & ipc_server_a, std::unique_ptr & ipc_rpc_processor_a, std::unique_ptr & node_rpc_config_a); + rpc_context (std::shared_ptr & rpc_a, std::shared_ptr & ipc_server_a, std::unique_ptr & ipc_rpc_processor_a, std::unique_ptr & node_rpc_config_a); std::shared_ptr rpc; - std::unique_ptr ipc_server; + std::shared_ptr ipc_server; std::unique_ptr ipc_rpc_processor; std::unique_ptr node_rpc_config; };