Skip to content

Commit b116536

Browse files
ryanofskyjanus
authored andcommitted
ipc: Use EventLoopRef instead of addClient/removeClient
Use EventLoopRef to avoid reference counting bugs and be more exception safe and deal with removal of addClient/removeClient methods in bitcoin-core/libmultiprocess#160 A test update is also required due to bitcoin-core/libmultiprocess#160 to deal with changed reference count semantics. In IpcPipeTest(), it is now necessary to destroy the client Proxy object instead of just the client Connection object to decrease the event loop reference count and allow the loop to exit so the test does not hang on shutdown.
1 parent 1b74ca2 commit b116536

File tree

2 files changed

+7
-15
lines changed

2 files changed

+7
-15
lines changed

src/ipc/capnp/protocol.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,7 @@ class CapnpProtocol : public Protocol
4141
public:
4242
~CapnpProtocol() noexcept(true)
4343
{
44-
if (m_loop) {
45-
std::unique_lock<std::mutex> lock(m_loop->m_mutex);
46-
m_loop->removeClient(lock);
47-
}
44+
m_loop_ref.reset();
4845
if (m_loop_thread.joinable()) m_loop_thread.join();
4946
assert(!m_loop);
5047
};
@@ -94,10 +91,7 @@ class CapnpProtocol : public Protocol
9491
m_loop_thread = std::thread([&] {
9592
util::ThreadRename("capnp-loop");
9693
m_loop.emplace(exe_name, &IpcLogFn, &m_context);
97-
{
98-
std::unique_lock<std::mutex> lock(m_loop->m_mutex);
99-
m_loop->addClient(lock);
100-
}
94+
m_loop_ref.emplace(*m_loop);
10195
promise.set_value();
10296
m_loop->loop();
10397
m_loop.reset();
@@ -106,13 +100,12 @@ class CapnpProtocol : public Protocol
106100
}
107101
Context m_context;
108102
std::thread m_loop_thread;
103+
//! EventLoop object which manages I/O events for all connections.
109104
std::optional<mp::EventLoop> m_loop;
110105
//! Reference to the same EventLoop. Increments the loop’s refcount on
111106
//! creation, decrements on destruction. The loop thread exits when the
112107
//! refcount reaches 0. Other IPC objects also hold their own EventLoopRef.
113108
std::optional<mp::EventLoopRef> m_loop_ref;
114-
//! Connection to parent, if this is a child process spawned by a parent process.
115-
mp::Connection* m_parent_connection{nullptr};
116109
};
117110
} // namespace
118111

src/test/ipc_test.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,17 +55,16 @@ void IpcPipeTest()
5555
{
5656
// Setup: create FooImplementation object and listen for FooInterface requests
5757
std::promise<std::unique_ptr<mp::ProxyClient<gen::FooInterface>>> foo_promise;
58-
std::function<void()> disconnect_client;
5958
std::thread thread([&]() {
6059
mp::EventLoop loop("IpcPipeTest", [](bool raise, const std::string& log) { LogInfo("LOG%i: %s", raise, log); });
6160
auto pipe = loop.m_io_context.provider->newTwoWayPipe();
6261

6362
auto connection_client = std::make_unique<mp::Connection>(loop, kj::mv(pipe.ends[0]));
6463
auto foo_client = std::make_unique<mp::ProxyClient<gen::FooInterface>>(
6564
connection_client->m_rpc_system->bootstrap(mp::ServerVatId().vat_id).castAs<gen::FooInterface>(),
66-
connection_client.get(), /* destroy_connection= */ false);
65+
connection_client.get(), /* destroy_connection= */ true);
66+
connection_client.release();
6767
foo_promise.set_value(std::move(foo_client));
68-
disconnect_client = [&] { loop.sync([&] { connection_client.reset(); }); };
6968

7069
auto connection_server = std::make_unique<mp::Connection>(loop, kj::mv(pipe.ends[1]), [&](mp::Connection& connection) {
7170
auto foo_server = kj::heap<mp::ProxyServer<gen::FooInterface>>(std::make_shared<FooImplementation>(), connection);
@@ -106,8 +105,8 @@ void IpcPipeTest()
106105
auto script2{foo->passScript(script1)};
107106
BOOST_CHECK_EQUAL(HexStr(script1), HexStr(script2));
108107

109-
// Test cleanup: disconnect pipe and join thread
110-
disconnect_client();
108+
// Test cleanup: disconnect and join thread
109+
foo.reset();
111110
thread.join();
112111
}
113112

0 commit comments

Comments
 (0)