Skip to content

Commit

Permalink
Add ipc::Context and ipc::capnp::Context structs
Browse files Browse the repository at this point in the history
These are currently empty structs but they will be used to pass some
function and object pointers from bitcoin application code to IPC hooks
that run, for example, when a remote object is created or destroyed, or
a new process is created.
  • Loading branch information
ryanofsky committed Jun 10, 2021
1 parent 1704bbf commit 3e33d17
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -840,9 +840,11 @@ EXTRA_DIST += $(libbitcoin_ipc_mpgen_input)
if BUILD_MULTIPROCESS
LIBBITCOIN_IPC=libbitcoin_ipc.a
libbitcoin_ipc_a_SOURCES = \
ipc/capnp/context.h \
ipc/capnp/init-types.h \
ipc/capnp/protocol.cpp \
ipc/capnp/protocol.h \
ipc/context.h \
ipc/exception.h \
ipc/interfaces.cpp \
ipc/process.cpp \
Expand Down
7 changes: 7 additions & 0 deletions src/interfaces/ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include <memory>
#include <typeindex>

namespace ipc {
struct Context;
} // namespace ipc

namespace interfaces {
class Init;

Expand Down Expand Up @@ -58,6 +62,9 @@ class Ipc
addCleanup(typeid(Interface), &iface, std::move(cleanup));
}

//! IPC context struct accessor (see struct definition for more description).
virtual ipc::Context& context() = 0;

protected:
//! Internal implementation of public addCleanup method (above) as a
//! type-erased virtual function, since template functions can't be virtual.
Expand Down
23 changes: 23 additions & 0 deletions src/ipc/capnp/context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_IPC_CAPNP_CONTEXT_H
#define BITCOIN_IPC_CAPNP_CONTEXT_H

#include <ipc/context.h>

namespace ipc {
namespace capnp {
//! Cap'n Proto context struct. Generally the parent ipc::Context struct should
//! be used instead of this struct to give all IPC protocols access to
//! application state, so there aren't unnecessary differences between IPC
//! protocols. But this specialized struct can be used to pass capnp-specific
//! function and object types to capnp hooks.
struct Context : ipc::Context
{
};
} // namespace capnp
} // namespace ipc

#endif // BITCOIN_IPC_CAPNP_CONTEXT_H
7 changes: 5 additions & 2 deletions src/ipc/capnp/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <interfaces/init.h>
#include <ipc/capnp/context.h>
#include <ipc/capnp/init.capnp.h>
#include <ipc/capnp/init.capnp.proxy.h>
#include <ipc/capnp/protocol.h>
Expand Down Expand Up @@ -54,7 +55,7 @@ class CapnpProtocol : public Protocol
{
assert(!m_loop);
mp::g_thread_context.thread_name = mp::ThreadName(exe_name);
m_loop.emplace(exe_name, &IpcLogFn, nullptr);
m_loop.emplace(exe_name, &IpcLogFn, &m_context);
mp::ServeStream<messages::Init>(*m_loop, fd, init);
m_loop->loop();
m_loop.reset();
Expand All @@ -63,13 +64,14 @@ class CapnpProtocol : public Protocol
{
mp::ProxyTypeRegister::types().at(type)(iface).cleanup.emplace_back(std::move(cleanup));
}
Context& context() override { return m_context; }
void startLoop(const char* exe_name)
{
if (m_loop) return;
std::promise<void> promise;
m_loop_thread = std::thread([&] {
util::ThreadRename("capnp-loop");
m_loop.emplace(exe_name, &IpcLogFn, nullptr);
m_loop.emplace(exe_name, &IpcLogFn, &m_context);
{
std::unique_lock<std::mutex> lock(m_loop->m_mutex);
m_loop->addClient(lock);
Expand All @@ -80,6 +82,7 @@ class CapnpProtocol : public Protocol
});
promise.get_future().wait();
}
Context m_context;
std::thread m_loop_thread;
std::optional<mp::EventLoop> m_loop;
};
Expand Down
19 changes: 19 additions & 0 deletions src/ipc/context.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) 2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_IPC_CONTEXT_H
#define BITCOIN_IPC_CONTEXT_H

namespace ipc {
//! Context struct used to give IPC protocol implementations or implementation
//! hooks access to application state, in case they need to run extra code that
//! isn't needed within a single process, like code copying global state from an
//! existing process to a new process when it's initialized, or code dealing
//! with shared objects that are created or destroyed remotely.
struct Context
{
};
} // namespace ipc

#endif // BITCOIN_IPC_CONTEXT_H
1 change: 1 addition & 0 deletions src/ipc/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class IpcImpl : public interfaces::Ipc
{
m_protocol->addCleanup(type, iface, std::move(cleanup));
}
Context& context() override { return m_protocol->context(); }
const char* m_exe_name;
const char* m_process_argv0;
interfaces::Init& m_init;
Expand Down
5 changes: 5 additions & 0 deletions src/ipc/protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <typeindex>

namespace ipc {
struct Context;

//! IPC protocol interface for calling IPC methods over sockets.
//!
//! There may be different implementations of this interface for different IPC
Expand All @@ -33,6 +35,9 @@ class Protocol
//! Add cleanup callback to interface that will run when the interface is
//! deleted.
virtual void addCleanup(std::type_index type, void* iface, std::function<void()> cleanup) = 0;

//! Context accessor.
virtual Context& context() = 0;
};
} // namespace ipc

Expand Down

0 comments on commit 3e33d17

Please sign in to comment.