7#include <ipc/capnp/init.capnp.h>
8#include <ipc/capnp/init.capnp.proxy.h>
26#include <sys/socket.h>
27#include <system_error>
34mp::Log GetRequestedIPCLogLevel()
43void IpcLogFn(mp::LogMessage message)
45 switch (message.
level) {
63 throw Exception(message.
message);
71class CapnpProtocol :
public Protocol
74 CapnpProtocol(
const char* exe_name) : m_exe_name{exe_name} {}
75 ~CapnpProtocol() noexcept(true)
78 if (m_loop_thread.joinable()) m_loop_thread.join();
81 std::unique_ptr<interfaces::Init> connect(
mp::Stream stream)
override
86 void listen(
mp::SocketId listen_fd, interfaces::Init& init)
override
89 if (::listen(listen_fd, 5) != 0) {
90 throw std::system_error(errno, std::system_category());
94 void serve(interfaces::Init& init,
const std::function<
mp::Stream()>& make_stream)
override
98 mp::LogOptions opts = {
100 .log_level = GetRequestedIPCLogLevel()
102 m_loop.emplace(m_exe_name, std::move(opts), &m_context);
104 m_parent_connection = &m_loop->m_incoming_connections.back();
108 void disconnectIncoming()
override
115 m_loop->m_incoming_connections.remove_if([
this](mp::Connection& c) {
return &c != m_parent_connection; });
123 void addCleanup(std::type_index type,
void* iface, std::function<
void()> cleanup)
override
127 Context& context()
override {
return m_context; }
131 std::promise<void> promise;
132 m_loop_thread = std::thread([&] {
134 mp::LogOptions opts = {
136 .log_level = GetRequestedIPCLogLevel()
138 m_loop.emplace(m_exe_name, std::move(opts), &m_context);
139 m_loop_ref.emplace(*m_loop);
144 promise.get_future().wait();
146 const char* m_exe_name;
149 std::optional<mp::EventLoop> m_loop;
153 std::optional<mp::EventLoopRef> m_loop_ref;
155 mp::Connection* m_parent_connection{
nullptr};
156 std::thread m_loop_thread;
160std::unique_ptr<Protocol>
MakeCapnpProtocol(
const char* exe_name) {
return std::make_unique<CapnpProtocol>(exe_name); }
#define LogTrace(category,...)
#define LogDebug(category,...)
std::unique_ptr< Protocol > MakeCapnpProtocol(const char *exe_name)
void ListenConnections(EventLoop &loop, int fd, InitImpl &init, std::optional< size_t > max_connections=std::nullopt)
ThreadContext & CurrentThread()
void ServeStream(EventLoop &loop, int fd, InitImpl &init)
std::string ThreadName(const char *exe_name)
Format current thread name as "{exe_name}-{$pid}/{thread_name}-{$tid}".
Stream MakeStream(EventLoop &, SocketId socket)
std::unique_ptr< ProxyClient< InitInterface > > ConnectStream(EventLoop &loop, int fd)
Log
Log flags. Update stringify function if changed!
bool ShouldDebugLog(Category category)
Return whether messages with specified category should be debug logged.
bool ShouldTraceLog(Category category)
Return whether messages with specified category should be trace logged.
void ThreadRename(const std::string &)
Log level
The severity level of this message.
std::string message
Message to be logged.
std::string thread_name
Identifying string for debug.