2020-09-12 11:44:00 +02:00
|
|
|
/*
|
2024-09-06 06:47:26 +02:00
|
|
|
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
|
2025-04-07 04:17:36 +02:00
|
|
|
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
2022-03-03 11:37:49 -07:00
|
|
|
* Copyright (c) 2022, the SerenityOS developers.
|
2020-09-12 11:44:00 +02:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-09-12 11:44:00 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2024-06-28 14:24:49 +02:00
|
|
|
#include <AK/Forward.h>
|
2024-04-17 16:46:24 -06:00
|
|
|
#include <AK/Queue.h>
|
2024-06-28 14:24:49 +02:00
|
|
|
#include <LibCore/EventReceiver.h>
|
2024-04-17 16:46:24 -06:00
|
|
|
#include <LibIPC/File.h>
|
2021-10-23 21:48:42 +02:00
|
|
|
#include <LibIPC/Forward.h>
|
2025-04-05 00:05:20 +02:00
|
|
|
#include <LibIPC/Message.h>
|
2024-10-22 15:47:33 -06:00
|
|
|
#include <LibIPC/Transport.h>
|
2020-09-12 11:44:00 +02:00
|
|
|
|
|
|
|
namespace IPC {
|
|
|
|
|
2023-08-06 18:09:39 +02:00
|
|
|
class ConnectionBase : public Core::EventReceiver {
|
2021-10-23 21:48:42 +02:00
|
|
|
C_OBJECT_ABSTRACT(ConnectionBase);
|
|
|
|
|
2020-09-12 11:44:00 +02:00
|
|
|
public:
|
2024-06-28 14:24:49 +02:00
|
|
|
virtual ~ConnectionBase() override;
|
2021-10-23 21:48:42 +02:00
|
|
|
|
2024-06-28 14:24:49 +02:00
|
|
|
[[nodiscard]] bool is_open() const;
|
2021-11-28 09:59:36 +01:00
|
|
|
ErrorOr<void> post_message(Message const&);
|
2025-04-10 20:26:46 +02:00
|
|
|
ErrorOr<void> post_message(MessageBuffer);
|
2021-10-23 21:48:42 +02:00
|
|
|
|
|
|
|
void shutdown();
|
|
|
|
virtual void die() { }
|
|
|
|
|
2025-04-08 22:01:46 +02:00
|
|
|
Transport& transport() const { return *m_transport; }
|
2021-10-23 21:48:42 +02:00
|
|
|
|
2022-10-05 20:09:55 +02:00
|
|
|
protected:
|
2025-04-08 22:01:46 +02:00
|
|
|
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Transport>, u32 local_endpoint_magic);
|
2022-10-05 20:09:55 +02:00
|
|
|
|
2021-10-23 21:48:42 +02:00
|
|
|
virtual void may_have_become_unresponsive() { }
|
|
|
|
virtual void did_become_responsive() { }
|
2022-06-10 17:21:00 +02:00
|
|
|
virtual void shutdown_with_error(Error const&);
|
2025-04-10 20:26:46 +02:00
|
|
|
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<File>&) = 0;
|
2021-10-23 21:48:42 +02:00
|
|
|
|
2021-10-23 22:59:04 +02:00
|
|
|
OwnPtr<IPC::Message> wait_for_specific_endpoint_message_impl(u32 endpoint_magic, int message_id);
|
2024-10-22 15:47:33 -06:00
|
|
|
void wait_for_transport_to_become_readable();
|
2021-11-07 11:59:43 +01:00
|
|
|
ErrorOr<void> drain_messages_from_peer();
|
2021-10-23 22:16:53 +02:00
|
|
|
|
2021-10-23 22:59:04 +02:00
|
|
|
void handle_messages();
|
2021-10-23 21:48:42 +02:00
|
|
|
|
|
|
|
IPC::Stub& m_local_stub;
|
|
|
|
|
2025-04-08 22:01:46 +02:00
|
|
|
NonnullOwnPtr<Transport> m_transport;
|
2022-10-05 13:54:09 +02:00
|
|
|
|
2021-10-23 21:48:42 +02:00
|
|
|
RefPtr<Core::Timer> m_responsiveness_timer;
|
|
|
|
|
2023-03-06 17:16:25 +01:00
|
|
|
Vector<NonnullOwnPtr<Message>> m_unprocessed_messages;
|
2021-10-23 22:59:04 +02:00
|
|
|
|
|
|
|
u32 m_local_endpoint_magic { 0 };
|
2021-10-23 21:48:42 +02:00
|
|
|
};
|
2021-05-03 08:46:40 +02:00
|
|
|
|
2021-10-23 21:48:42 +02:00
|
|
|
template<typename LocalEndpoint, typename PeerEndpoint>
|
|
|
|
class Connection : public ConnectionBase {
|
|
|
|
public:
|
2025-04-08 22:01:46 +02:00
|
|
|
Connection(IPC::Stub& local_stub, NonnullOwnPtr<Transport> transport)
|
2025-04-07 23:41:24 +02:00
|
|
|
: ConnectionBase(local_stub, move(transport), LocalEndpoint::static_magic())
|
2020-09-12 11:44:00 +02:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename MessageType>
|
|
|
|
OwnPtr<MessageType> wait_for_specific_message()
|
|
|
|
{
|
|
|
|
return wait_for_specific_endpoint_message<MessageType, LocalEndpoint>();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename RequestType, typename... Args>
|
2021-04-20 10:53:31 +03:00
|
|
|
NonnullOwnPtr<typename RequestType::ResponseType> send_sync(Args&&... args)
|
2020-09-12 11:44:00 +02:00
|
|
|
{
|
2021-11-28 09:59:36 +01:00
|
|
|
MUST(post_message(RequestType(forward<Args>(args)...)));
|
2020-09-12 11:44:00 +02:00
|
|
|
auto response = wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
|
2021-02-23 20:42:32 +01:00
|
|
|
VERIFY(response);
|
2021-04-20 10:53:31 +03:00
|
|
|
return response.release_nonnull();
|
2020-09-12 11:44:00 +02:00
|
|
|
}
|
|
|
|
|
2021-02-20 11:07:29 +01:00
|
|
|
template<typename RequestType, typename... Args>
|
|
|
|
OwnPtr<typename RequestType::ResponseType> send_sync_but_allow_failure(Args&&... args)
|
|
|
|
{
|
2021-11-28 09:59:36 +01:00
|
|
|
if (post_message(RequestType(forward<Args>(args)...)).is_error())
|
|
|
|
return nullptr;
|
2021-02-20 11:07:29 +01:00
|
|
|
return wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
|
|
|
|
}
|
|
|
|
|
2020-09-12 11:44:00 +02:00
|
|
|
protected:
|
|
|
|
template<typename MessageType, typename Endpoint>
|
|
|
|
OwnPtr<MessageType> wait_for_specific_endpoint_message()
|
|
|
|
{
|
2021-10-23 22:59:04 +02:00
|
|
|
if (auto message = wait_for_specific_endpoint_message_impl(Endpoint::static_magic(), MessageType::static_message_id()))
|
2021-10-23 22:21:47 +02:00
|
|
|
return message.template release_nonnull<MessageType>();
|
2021-01-10 16:29:28 -07:00
|
|
|
return {};
|
2020-09-12 11:44:00 +02:00
|
|
|
}
|
|
|
|
|
2025-04-10 20:26:46 +02:00
|
|
|
virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<File>& fds) override
|
2020-09-12 11:44:00 +02:00
|
|
|
{
|
2024-06-28 12:17:47 +02:00
|
|
|
auto local_message = LocalEndpoint::decode_message(bytes, fds);
|
|
|
|
if (!local_message.is_error())
|
|
|
|
return local_message.release_value();
|
|
|
|
|
|
|
|
auto peer_message = PeerEndpoint::decode_message(bytes, fds);
|
|
|
|
if (!peer_message.is_error())
|
|
|
|
return peer_message.release_value();
|
|
|
|
|
|
|
|
return nullptr;
|
2020-09-12 11:44:00 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|