| 
									
										
										
										
											2020-09-12 11:44:00 +02:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											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>
 | 
					
						
							| 
									
										
										
										
											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&); | 
					
						
							| 
									
										
										
										
											2021-10-23 21:48:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     void shutdown(); | 
					
						
							|  |  |  |     virtual void die() { } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  |     Core::LocalSocket& socket() { return *m_socket; } | 
					
						
							| 
									
										
										
										
											2021-10-23 21:48:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-05 20:09:55 +02:00
										 |  |  | protected: | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  |     explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::LocalSocket>, 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&); | 
					
						
							| 
									
										
										
										
											2024-06-28 12:17:47 +02:00
										 |  |  |     virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<IPC::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); | 
					
						
							| 
									
										
										
										
											2021-10-23 21:48:42 +02:00
										 |  |  |     void wait_for_socket_to_become_readable(); | 
					
						
							| 
									
										
										
										
											2021-11-07 11:59:43 +01:00
										 |  |  |     ErrorOr<Vector<u8>> read_as_much_as_possible_from_socket_without_blocking(); | 
					
						
							|  |  |  |     ErrorOr<void> drain_messages_from_peer(); | 
					
						
							| 
									
										
										
										
											2024-06-28 12:17:47 +02:00
										 |  |  |     void try_parse_messages(Vector<u8> const& bytes, size_t& index); | 
					
						
							| 
									
										
										
										
											2021-10-23 22:16:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-28 09:59:36 +01:00
										 |  |  |     ErrorOr<void> post_message(MessageBuffer); | 
					
						
							| 
									
										
										
										
											2021-10-23 22:59:04 +02:00
										 |  |  |     void handle_messages(); | 
					
						
							| 
									
										
										
										
											2021-10-23 21:48:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     IPC::Stub& m_local_stub; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  |     NonnullOwnPtr<Core::LocalSocket> m_socket; | 
					
						
							| 
									
										
										
										
											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; | 
					
						
							| 
									
										
										
										
											2024-04-17 16:46:24 -06:00
										 |  |  |     Queue<IPC::File> m_unprocessed_fds; | 
					
						
							| 
									
										
										
										
											2021-10-23 21:48:42 +02:00
										 |  |  |     ByteBuffer m_unprocessed_bytes; | 
					
						
							| 
									
										
										
										
											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: | 
					
						
							| 
									
										
										
										
											2023-02-08 23:05:44 +01:00
										 |  |  |     Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::LocalSocket> socket) | 
					
						
							| 
									
										
										
										
											2021-10-23 22:59:04 +02:00
										 |  |  |         : ConnectionBase(local_stub, move(socket), 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
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-28 12:17:47 +02:00
										 |  |  |     virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<IPC::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
										 |  |  |     } | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |