Connection.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, the SerenityOS developers.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/Forward.h>
  9. #include <AK/Queue.h>
  10. #include <LibCore/EventReceiver.h>
  11. #include <LibIPC/File.h>
  12. #include <LibIPC/Forward.h>
  13. namespace IPC {
  14. class ConnectionBase : public Core::EventReceiver {
  15. C_OBJECT_ABSTRACT(ConnectionBase);
  16. public:
  17. virtual ~ConnectionBase() override;
  18. [[nodiscard]] bool is_open() const;
  19. ErrorOr<void> post_message(Message const&);
  20. void shutdown();
  21. virtual void die() { }
  22. Core::LocalSocket& socket() { return *m_socket; }
  23. protected:
  24. explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::LocalSocket>, u32 local_endpoint_magic);
  25. virtual void may_have_become_unresponsive() { }
  26. virtual void did_become_responsive() { }
  27. virtual void shutdown_with_error(Error const&);
  28. virtual OwnPtr<Message> try_parse_message(ReadonlyBytes, Queue<IPC::File>&) = 0;
  29. OwnPtr<IPC::Message> wait_for_specific_endpoint_message_impl(u32 endpoint_magic, int message_id);
  30. void wait_for_socket_to_become_readable();
  31. ErrorOr<Vector<u8>> read_as_much_as_possible_from_socket_without_blocking();
  32. ErrorOr<void> drain_messages_from_peer();
  33. void try_parse_messages(Vector<u8> const& bytes, size_t& index);
  34. ErrorOr<void> post_message(MessageBuffer);
  35. void handle_messages();
  36. IPC::Stub& m_local_stub;
  37. NonnullOwnPtr<Core::LocalSocket> m_socket;
  38. RefPtr<Core::Timer> m_responsiveness_timer;
  39. Vector<NonnullOwnPtr<Message>> m_unprocessed_messages;
  40. Queue<IPC::File> m_unprocessed_fds;
  41. ByteBuffer m_unprocessed_bytes;
  42. u32 m_local_endpoint_magic { 0 };
  43. };
  44. template<typename LocalEndpoint, typename PeerEndpoint>
  45. class Connection : public ConnectionBase {
  46. public:
  47. Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::LocalSocket> socket)
  48. : ConnectionBase(local_stub, move(socket), LocalEndpoint::static_magic())
  49. {
  50. }
  51. template<typename MessageType>
  52. OwnPtr<MessageType> wait_for_specific_message()
  53. {
  54. return wait_for_specific_endpoint_message<MessageType, LocalEndpoint>();
  55. }
  56. template<typename RequestType, typename... Args>
  57. NonnullOwnPtr<typename RequestType::ResponseType> send_sync(Args&&... args)
  58. {
  59. MUST(post_message(RequestType(forward<Args>(args)...)));
  60. auto response = wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
  61. VERIFY(response);
  62. return response.release_nonnull();
  63. }
  64. template<typename RequestType, typename... Args>
  65. OwnPtr<typename RequestType::ResponseType> send_sync_but_allow_failure(Args&&... args)
  66. {
  67. if (post_message(RequestType(forward<Args>(args)...)).is_error())
  68. return nullptr;
  69. return wait_for_specific_endpoint_message<typename RequestType::ResponseType, PeerEndpoint>();
  70. }
  71. protected:
  72. template<typename MessageType, typename Endpoint>
  73. OwnPtr<MessageType> wait_for_specific_endpoint_message()
  74. {
  75. if (auto message = wait_for_specific_endpoint_message_impl(Endpoint::static_magic(), MessageType::static_message_id()))
  76. return message.template release_nonnull<MessageType>();
  77. return {};
  78. }
  79. virtual OwnPtr<Message> try_parse_message(ReadonlyBytes bytes, Queue<IPC::File>& fds) override
  80. {
  81. auto local_message = LocalEndpoint::decode_message(bytes, fds);
  82. if (!local_message.is_error())
  83. return local_message.release_value();
  84. auto peer_message = PeerEndpoint::decode_message(bytes, fds);
  85. if (!peer_message.is_error())
  86. return peer_message.release_value();
  87. return nullptr;
  88. }
  89. };
  90. }
  91. template<typename LocalEndpoint, typename PeerEndpoint>
  92. struct AK::Formatter<IPC::Connection<LocalEndpoint, PeerEndpoint>> : Formatter<Core::EventReceiver> {
  93. };