mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 05:32:22 +02:00
ipc, refactor: Update mp::SpawnProcess call
Use new SpawnProcess and StartSpawned functions to be compatible with an upcoming version of libmultiprocess which adds windows support.
This commit is contained in:
@@ -62,10 +62,9 @@ public:
|
||||
}
|
||||
std::unique_ptr<interfaces::Init> spawnProcess(const char* new_exe_name) override
|
||||
{
|
||||
mp::ProcessId pid;
|
||||
mp::SocketId fd = m_process->spawn(new_exe_name, m_process_argv0, pid);
|
||||
const auto [pid, socket] = m_process->spawn(new_exe_name, m_process_argv0);
|
||||
LogDebug(::BCLog::IPC, "Process %s pid %i launched\n", new_exe_name, pid);
|
||||
auto init = m_protocol->connect(m_protocol->makeStream(fd));
|
||||
auto init = m_protocol->connect(m_protocol->makeStream(socket));
|
||||
Ipc::addCleanup(*init, [this, new_exe_name, pid] {
|
||||
int status = m_process->waitSpawned(pid);
|
||||
LogDebug(::BCLog::IPC, "Process %s pid %i exited with status %i\n", new_exe_name, pid, status);
|
||||
|
||||
@@ -32,13 +32,13 @@ namespace {
|
||||
class ProcessImpl : public Process
|
||||
{
|
||||
public:
|
||||
mp::SocketId spawn(const std::string& new_exe_name, const fs::path& argv0_path, mp::ProcessId& pid) override
|
||||
std::tuple<mp::ProcessId, mp::SocketId> spawn(const std::string& new_exe_name, const fs::path& argv0_path) override
|
||||
{
|
||||
return mp::SpawnProcess(pid, [&](int fd) {
|
||||
return mp::SpawnProcess([&](std::string connect_info) {
|
||||
fs::path path = argv0_path;
|
||||
path.remove_filename();
|
||||
path /= fs::PathFromString(new_exe_name);
|
||||
return std::vector<std::string>{fs::PathToString(path), "-ipcfd", strprintf("%i", fd)};
|
||||
return std::vector<std::string>{fs::PathToString(path), "-ipcfd", std::move(connect_info)};
|
||||
});
|
||||
}
|
||||
int waitSpawned(mp::ProcessId pid) override { return mp::WaitProcess(pid); }
|
||||
@@ -56,11 +56,11 @@ public:
|
||||
// in combination with other arguments because the parent process
|
||||
// should be able to control the child process through the IPC protocol
|
||||
// without passing information out of band.
|
||||
const auto maybe_fd{ToIntegral<int32_t>(argv[2])};
|
||||
if (!maybe_fd) {
|
||||
throw std::runtime_error(strprintf("Invalid -ipcfd number '%s'", argv[2]));
|
||||
try {
|
||||
socket = mp::StartSpawned(argv[2]);
|
||||
} catch (const std::exception& e) {
|
||||
throw std::runtime_error(strprintf("Invalid -ipcfd number '%s' (%s)", argv[2], e.what()));
|
||||
}
|
||||
socket = *maybe_fd;
|
||||
return true;
|
||||
}
|
||||
mp::SocketId connect(const fs::path& data_dir,
|
||||
|
||||
@@ -25,7 +25,7 @@ public:
|
||||
virtual ~Process() = default;
|
||||
|
||||
//! Spawn process and return socket id for communicating with it.
|
||||
virtual mp::SocketId spawn(const std::string& new_exe_name, const fs::path& argv0_path, mp::ProcessId& pid) = 0;
|
||||
virtual std::tuple<mp::ProcessId, mp::SocketId> spawn(const std::string& new_exe_name, const fs::path& argv0_path) = 0;
|
||||
|
||||
//! Wait for spawned process to exit and return its exit code.
|
||||
virtual int waitSpawned(mp::ProcessId pid) = 0;
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
#ifndef BITCOIN_IPC_UTIL_H
|
||||
#define BITCOIN_IPC_UTIL_H
|
||||
|
||||
#include <tinyformat.h>
|
||||
#include <util/strencodings.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <kj/debug.h>
|
||||
#include <mp/util.h>
|
||||
#include <mp/version.h>
|
||||
@@ -34,6 +38,20 @@ inline std::array<SocketId, 2> SocketPair()
|
||||
KJ_SYSCALL(socketpair(AF_UNIX, SOCK_STREAM, 0, pair));
|
||||
return {pair[0], pair[1]};
|
||||
}
|
||||
|
||||
inline std::tuple<ProcessId, SocketId> SpawnProcess(const std::function<std::vector<std::string>(std::string)>& spawn_argv)
|
||||
{
|
||||
ProcessId pid;
|
||||
SocketId socket = SpawnProcess(pid, [&](int fd) { return spawn_argv(strprintf("%d", fd)); });
|
||||
return {pid, socket};
|
||||
}
|
||||
|
||||
inline SocketId StartSpawned(const std::string& connect_info)
|
||||
{
|
||||
auto socket = ToIntegral<SocketId>(connect_info);
|
||||
if (!socket) throw std::invalid_argument(strprintf("Invalid socket descriptor '%s'", connect_info));
|
||||
return *socket;
|
||||
}
|
||||
#endif
|
||||
} // namespace mp
|
||||
|
||||
|
||||
Reference in New Issue
Block a user