Skip to content

Commit 02f58e0

Browse files
vasildryanofsky
andcommitted
refactor: Remove DestructorCatcher and AsyncCallable
Use kj::Function instead of std::function to avoid the need for AsyncCallable and DestructorCatcher classes, which were used to work around the requirement that std::function objects need to be copyable. kj::Function does not have this requirement. Change is from #144 (comment) Co-authored-by: Ryan Ofsky <[email protected]>
1 parent d704579 commit 02f58e0

File tree

4 files changed

+14
-55
lines changed

4 files changed

+14
-55
lines changed

include/mp/proxy-io.h

+9-10
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@
1414

1515
#include <assert.h>
1616
#include <functional>
17-
#include <optional>
17+
#include <kj/function.h>
1818
#include <map>
1919
#include <memory>
20+
#include <optional>
2021
#include <sstream>
2122
#include <string>
2223

@@ -163,15 +164,15 @@ class EventLoop
163164

164165
//! Run function on event loop thread. Does not return until function completes.
165166
//! Must be called while the loop() function is active.
166-
void post(const std::function<void()>& fn);
167+
void post(kj::Function<void()> fn);
167168

168169
//! Wrapper around EventLoop::post that takes advantage of the
169170
//! fact that callable will not go out of scope to avoid requirement that it
170171
//! be copyable.
171172
template <typename Callable>
172173
void sync(Callable&& callable)
173174
{
174-
post(std::ref(callable));
175+
post(std::forward<Callable>(callable));
175176
}
176177

177178
//! Start asynchronous worker thread if necessary. This is only done if
@@ -211,7 +212,7 @@ class EventLoop
211212
std::thread m_async_thread;
212213

213214
//! Callback function to run on event loop thread during post() or sync() call.
214-
const std::function<void()>* m_post_fn = nullptr;
215+
kj::Function<void()>* m_post_fn = nullptr;
215216

216217
//! Callback functions to run on async thread.
217218
CleanupList m_async_fns;
@@ -279,11 +280,9 @@ struct Waiter
279280
// in the case where a capnp response is sent and a brand new
280281
// request is immediately received.
281282
while (m_fn) {
282-
auto fn = std::move(m_fn);
283-
m_fn = nullptr;
284-
lock.unlock();
285-
fn();
286-
lock.lock();
283+
auto fn = std::move(*m_fn);
284+
m_fn.reset();
285+
Unlock(lock, fn);
287286
}
288287
const bool done = pred();
289288
return done;
@@ -292,7 +291,7 @@ struct Waiter
292291

293292
std::mutex m_mutex;
294293
std::condition_variable m_cv;
295-
std::function<void()> m_fn;
294+
std::optional<kj::Function<void()>> m_fn;
296295
};
297296

298297
//! Object holding network & rpc state associated with either an incoming server

include/mp/type-context.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn&
6464
auto future = kj::newPromiseAndFulfiller<typename ServerContext::CallContext>();
6565
auto& server = server_context.proxy_server;
6666
int req = server_context.req;
67-
auto invoke = MakeAsyncCallable(
68-
[fulfiller = kj::mv(future.fulfiller),
67+
auto invoke = [fulfiller = kj::mv(future.fulfiller),
6968
call_context = kj::mv(server_context.call_context), &server, req, fn, args...]() mutable {
7069
const auto& params = call_context.getParams();
7170
Context::Reader context_arg = Accessor::get(params);
@@ -143,14 +142,14 @@ auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn&
143142
fulfiller_dispose->reject(kj::mv(*exception));
144143
});
145144
}
146-
});
145+
};
147146

148147
// Lookup Thread object specified by the client. The specified thread should
149148
// be a local Thread::Server object, but it needs to be looked up
150149
// asynchronously with getLocalServer().
151150
auto thread_client = context_arg.getThread();
152151
return server.m_context.connection->m_threads.getLocalServer(thread_client)
153-
.then([&server, invoke, req](const kj::Maybe<Thread::Server&>& perhaps) {
152+
.then([&server, invoke = kj::mv(invoke), req](const kj::Maybe<Thread::Server&>& perhaps) mutable {
154153
// Assuming the thread object is found, pass it a pointer to the
155154
// `invoke` lambda above which will invoke the function on that
156155
// thread.

include/mp/util.h

-40
Original file line numberDiff line numberDiff line change
@@ -161,46 +161,6 @@ void Unlock(Lock& lock, Callback&& callback)
161161
callback();
162162
}
163163

164-
//! Needed for libc++/macOS compatibility. Lets code work with shared_ptr nothrow declaration
165-
//! https://github.com/capnproto/capnproto/issues/553#issuecomment-328554603
166-
template <typename T>
167-
struct DestructorCatcher
168-
{
169-
T value;
170-
template <typename... Params>
171-
DestructorCatcher(Params&&... params) : value(kj::fwd<Params>(params)...)
172-
{
173-
}
174-
~DestructorCatcher() noexcept try {
175-
} catch (const kj::Exception& e) { // NOLINT(bugprone-empty-catch)
176-
}
177-
};
178-
179-
//! Wrapper around callback function for compatibility with std::async.
180-
//!
181-
//! std::async requires callbacks to be copyable and requires noexcept
182-
//! destructors, but this doesn't work well with kj types which are generally
183-
//! move-only and not noexcept.
184-
template <typename Callable>
185-
struct AsyncCallable
186-
{
187-
AsyncCallable(Callable&& callable) : m_callable(std::make_shared<DestructorCatcher<Callable>>(std::move(callable)))
188-
{
189-
}
190-
AsyncCallable(const AsyncCallable&) = default;
191-
AsyncCallable(AsyncCallable&&) = default;
192-
~AsyncCallable() noexcept = default;
193-
ResultOf<Callable> operator()() const { return (m_callable->value)(); }
194-
mutable std::shared_ptr<DestructorCatcher<Callable>> m_callable;
195-
};
196-
197-
//! Construct AsyncCallable object.
198-
template <typename Callable>
199-
AsyncCallable<std::remove_reference_t<Callable>> MakeAsyncCallable(Callable&& callable)
200-
{
201-
return std::move(callable);
202-
}
203-
204164
//! Format current thread name as "{exe_name}-{$pid}/{thread_name}-{$tid}".
205165
std::string ThreadName(const char* exe_name);
206166

src/mp/proxy.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <kj/common.h>
2323
#include <kj/debug.h>
2424
#include <kj/exception.h>
25+
#include <kj/function.h>
2526
#include <kj/memory.h>
2627
#include <map>
2728
#include <memory>
@@ -247,7 +248,7 @@ void EventLoop::loop()
247248
m_post_fd = -1;
248249
}
249250

250-
void EventLoop::post(const std::function<void()>& fn)
251+
void EventLoop::post(kj::Function<void()> fn)
251252
{
252253
if (std::this_thread::get_id() == m_thread_id) {
253254
fn();

0 commit comments

Comments
 (0)