... change EventLoop::post method to use kj::Function ...
Quick attempt at doing that, I am not sure how to resolve the compilation error in sync():
<details>
<summary>[patch] Remove DestructorCatcher and AsyncCallable</summary>
diff --git i/include/mp/proxy-io.h w/include/mp/proxy-io.h
index 4430a42..14d5906 100644
--- i/include/mp/proxy-io.h
+++ w/include/mp/proxy-io.h
@@ -8,12 +8,13 @@
#include <mp/proxy.h>
#include <mp/util.h>
#include <mp/proxy.capnp.h>
#include <capnp/rpc-twoparty.h>
+#include <kj/function.h>
#include <assert.h>
#include <functional>
#include <optional>
#include <map>
#include <memory>
@@ -141,20 +142,22 @@ public:
//! called once from the m_thread_id thread. This will block until
//! the m_num_clients reference count is 0.
void loop();
//! Run function on event loop thread. Does not return until function completes.
//! Must be called while the loop() function is active.
- void post(const std::function<void()>& fn);
+ void post(kj::Function<void()>& fn);
//! Wrapper around EventLoop::post that takes advantage of the
//! fact that callable will not go out of scope to avoid requirement that it
//! be copyable.
template <typename Callable>
void sync(Callable&& callable)
{
+ // XXX
+ // error: no viable conversion from 'reference_wrapper<(lambda at libmultiprocess/include/mp/proxy-io.h:427:43)>' to 'kj::Function<void ()>'
return post(std::ref(callable));
}
//! Start asynchronous worker thread if necessary. This is only done if
//! there are ProxyServerBase::m_impl objects that need to be destroyed
//! asynchronously, without tying up the event loop thread. This can happen
@@ -192,13 +195,13 @@ public:
//! Handle of an async worker thread. Joined on destruction. Unset if async
//! method has not been called.
std::thread m_async_thread;
//! Callback function to run on event loop thread during post() or sync() call.
- const std::function<void()>* m_post_fn = nullptr;
+ kj::Function<void()>* m_post_fn = nullptr;
//! Callback functions to run on async thread.
CleanupList m_async_fns;
//! Pipe read handle used to wake up the event loop thread.
int m_wait_fd = -1;
diff --git i/include/mp/type-context.h w/include/mp/type-context.h
index 7c12afe..40d7cc1 100644
--- i/include/mp/type-context.h
+++ w/include/mp/type-context.h
@@ -61,13 +61,13 @@ auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn&
{
const auto& params = server_context.call_context.getParams();
Context::Reader context_arg = Accessor::get(params);
auto future = kj::newPromiseAndFulfiller<typename ServerContext::CallContext>();
auto& server = server_context.proxy_server;
int req = server_context.req;
- auto invoke = MakeAsyncCallable(
+ auto invoke =
[fulfiller = kj::mv(future.fulfiller),
call_context = kj::mv(server_context.call_context), &server, req, fn, args...]() mutable {
const auto& params = call_context.getParams();
Context::Reader context_arg = Accessor::get(params);
ServerContext server_context{server, call_context, req};
bool disconnected{false};
@@ -140,13 +140,13 @@ auto PassField(Priority<1>, TypeList<>, ServerContext& server_context, const Fn&
{
server.m_context.connection->m_loop.sync([&]() {
auto fulfiller_dispose = kj::mv(fulfiller);
fulfiller_dispose->reject(kj::mv(*exception));
});
}
- });
+ };
// Lookup Thread object specified by the client. The specified thread should
// be a local Thread::Server object, but it needs to be looked up
// asynchronously with getLocalServer().
auto thread_client = context_arg.getThread();
return server.m_context.connection->m_threads.getLocalServer(thread_client)
diff --git i/include/mp/util.h w/include/mp/util.h
index 0569c44..4fdfd4e 100644
--- i/include/mp/util.h
+++ w/include/mp/util.h
@@ -6,12 +6,13 @@
#define MP_UTIL_H
#include <capnp/schema.h>
#include <cstddef>
#include <functional>
#include <future>
+#include <kj/debug.h>
#include <kj/common.h>
#include <kj/exception.h>
#include <kj/string-tree.h>
#include <memory>
#include <string.h>
#include <string>
@@ -143,52 +144,12 @@ template <typename Lock, typename Callback>
void Unlock(Lock& lock, Callback&& callback)
{
UnlockGuard<Lock> unlock(lock); // NOLINT(misc-const-correctness)
callback();
}
-//! Needed for libc++/macOS compatibility. Lets code work with shared_ptr nothrow declaration
-//! https://github.com/capnproto/capnproto/issues/553#issuecomment-328554603
-template <typename T>
-struct DestructorCatcher
-{
- T value;
- template <typename... Params>
- DestructorCatcher(Params&&... params) : value(kj::fwd<Params>(params)...)
- {
- }
- ~DestructorCatcher() noexcept try {
- } catch (const kj::Exception& e) { // NOLINT(bugprone-empty-catch)
- }
-};
-
-//! Wrapper around callback function for compatibility with std::async.
-//!
-//! std::async requires callbacks to be copyable and requires noexcept
-//! destructors, but this doesn't work well with kj types which are generally
-//! move-only and not noexcept.
-template <typename Callable>
-struct AsyncCallable
-{
- AsyncCallable(Callable&& callable) : m_callable(std::make_shared<DestructorCatcher<Callable>>(std::move(callable)))
- {
- }
- AsyncCallable(const AsyncCallable&) = default;
- AsyncCallable(AsyncCallable&&) = default;
- ~AsyncCallable() noexcept = default;
- ResultOf<Callable> operator()() const { return (m_callable->value)(); }
- mutable std::shared_ptr<DestructorCatcher<Callable>> m_callable;
-};
-
-//! Construct AsyncCallable object.
-template <typename Callable>
-AsyncCallable<std::remove_reference_t<Callable>> MakeAsyncCallable(Callable&& callable)
-{
- return std::move(callable);
-}
-
//! Format current thread name as "{exe_name}-{$pid}/{thread_name}-{$tid}".
std::string ThreadName(const char* exe_name);
//! Escape binary string for use in log so it doesn't trigger unicode decode
//! errors in python unit tests.
std::string LogEscape(const kj::StringTree& string);
diff --git i/src/mp/proxy.cpp w/src/mp/proxy.cpp
index ca094e3..5b2fdf6 100644
--- i/src/mp/proxy.cpp
+++ w/src/mp/proxy.cpp
@@ -19,12 +19,13 @@
#include <future>
#include <kj/async-io.h>
#include <kj/async.h>
#include <kj/common.h>
#include <kj/debug.h>
#include <kj/exception.h>
+#include <kj/function.h>
#include <kj/memory.h>
#include <map>
#include <memory>
#include <mutex>
#include <stddef.h>
#include <stdexcept>
@@ -215,13 +216,13 @@ void EventLoop::loop()
KJ_SYSCALL(::close(post_fd));
std::unique_lock<std::mutex> lock(m_mutex); // NOLINT(misc-const-correctness)
m_wait_fd = -1;
m_post_fd = -1;
}
-void EventLoop::post(const std::function<void()>& fn)
+void EventLoop::post(kj::Function<void()>& fn)
{
if (std::this_thread::get_id() == m_thread_id) {
fn();
return;
}
std::unique_lock<std::mutex> lock(m_mutex);
</details>