diff options
author | Andreas Kling <kling@serenityos.org> | 2022-10-05 20:09:55 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-10-06 09:51:04 +0200 |
commit | b5681992e1caebeac2d95d84690e06dd99234439 (patch) | |
tree | bfbb1f5e6b831fdf8bbde9e92855345a9b636c8f /Userland | |
parent | f87778211776727f824eed588c5c2f9d4285f62c (diff) | |
download | serenity-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.cpp | 23 | ||||
-rw-r--r-- | Userland/Libraries/LibIPC/Connection.h | 16 |
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> |