summaryrefslogtreecommitdiff
path: root/Userland
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-10-05 20:09:55 +0200
committerAndreas Kling <kling@serenityos.org>2022-10-06 09:51:04 +0200
commitb5681992e1caebeac2d95d84690e06dd99234439 (patch)
treebfbb1f5e6b831fdf8bbde9e92855345a9b636c8f /Userland
parentf87778211776727f824eed588c5c2f9d4285f62c (diff)
downloadserenity-b5681992e1caebeac2d95d84690e06dd99234439.zip
LibIPC: Allow overriding the use of deferred_invoke()
This will allow Ladybird to use IPC::Connection without having an actively running Core::EventLoop. The abstraction here is not great, and we should think of something nicer, but we have to start somewhere.
Diffstat (limited to 'Userland')
-rw-r--r--Userland/Libraries/LibIPC/Connection.cpp23
-rw-r--r--Userland/Libraries/LibIPC/Connection.h16
2 files changed, 33 insertions, 6 deletions
diff --git a/Userland/Libraries/LibIPC/Connection.cpp b/Userland/Libraries/LibIPC/Connection.cpp
index f29ea1ecbd..465afd93de 100644
--- a/Userland/Libraries/LibIPC/Connection.cpp
+++ b/Userland/Libraries/LibIPC/Connection.cpp
@@ -12,14 +12,29 @@
namespace IPC {
+struct CoreEventLoopDeferredInvoker final : public DeferredInvoker {
+ virtual ~CoreEventLoopDeferredInvoker() = default;
+
+ virtual void schedule(Function<void()> callback) override
+ {
+ Core::deferred_invoke(move(callback));
+ }
+};
+
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, u32 local_endpoint_magic)
: m_local_stub(local_stub)
, m_socket(move(socket))
, m_local_endpoint_magic(local_endpoint_magic)
+ , m_deferred_invoker(make<CoreEventLoopDeferredInvoker>())
{
m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); });
}
+void ConnectionBase::set_deferred_invoker(NonnullOwnPtr<DeferredInvoker> deferred_invoker)
+{
+ m_deferred_invoker = move(deferred_invoker);
+}
+
void ConnectionBase::set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
{
m_fd_passing_socket = move(socket);
@@ -157,7 +172,9 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
auto bytes_read = maybe_bytes_read.release_value();
if (bytes_read.is_empty()) {
- deferred_invoke([this] { shutdown(); });
+ m_deferred_invoker->schedule([strong_this = NonnullRefPtr(*this)]() mutable {
+ strong_this->shutdown();
+ });
if (!bytes.is_empty())
break;
return Error::from_string_literal("IPC connection EOF");
@@ -194,8 +211,8 @@ ErrorOr<void> ConnectionBase::drain_messages_from_peer()
}
if (!m_unprocessed_messages.is_empty()) {
- deferred_invoke([this] {
- handle_messages();
+ m_deferred_invoker->schedule([strong_this = NonnullRefPtr(*this)]() mutable {
+ strong_this->handle_messages();
});
}
return {};
diff --git a/Userland/Libraries/LibIPC/Connection.h b/Userland/Libraries/LibIPC/Connection.h
index e2a41c0dc6..67e66139bd 100644
--- a/Userland/Libraries/LibIPC/Connection.h
+++ b/Userland/Libraries/LibIPC/Connection.h
@@ -27,6 +27,13 @@
namespace IPC {
+// NOTE: This is an abstraction to allow using IPC::Connection without a Core::EventLoop.
+// FIXME: It's not particularly nice, think of something nicer.
+struct DeferredInvoker {
+ virtual ~DeferredInvoker() = default;
+ virtual void schedule(Function<void()>) = 0;
+};
+
class ConnectionBase : public Core::Object {
C_OBJECT_ABSTRACT(ConnectionBase);
@@ -34,6 +41,7 @@ public:
virtual ~ConnectionBase() override = default;
void set_fd_passing_socket(NonnullOwnPtr<Core::Stream::LocalSocket>);
+ void set_deferred_invoker(NonnullOwnPtr<DeferredInvoker>);
bool is_open() const { return m_socket->is_open(); }
ErrorOr<void> post_message(Message const&);
@@ -41,12 +49,12 @@ public:
void shutdown();
virtual void die() { }
-protected:
- explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
-
Core::Stream::LocalSocket& socket() { return *m_socket; }
Core::Stream::LocalSocket& fd_passing_socket();
+protected:
+ explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
+
virtual void may_have_become_unresponsive() { }
virtual void did_become_responsive() { }
virtual void try_parse_messages(Vector<u8> const& bytes, size_t& index) = 0;
@@ -71,6 +79,8 @@ protected:
ByteBuffer m_unprocessed_bytes;
u32 m_local_endpoint_magic { 0 };
+
+ NonnullOwnPtr<DeferredInvoker> m_deferred_invoker;
};
template<typename LocalEndpoint, typename PeerEndpoint>