diff --git a/Libraries/LibIPC/ClientConnection.h b/Libraries/LibIPC/ClientConnection.h index 0e2da07bf9..2b042db22d 100644 --- a/Libraries/LibIPC/ClientConnection.h +++ b/Libraries/LibIPC/ClientConnection.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -75,133 +76,38 @@ NonnullRefPtr new_client_connection(Args&&... args) return T::construct(forward(args)...) /* arghs */; } -template -class ClientConnection : public Core::Object { +template +class ClientConnection : public Connection { public: - ClientConnection(Endpoint& endpoint, NonnullRefPtr socket, int client_id) - : m_endpoint(endpoint) - , m_socket(move(socket)) + ClientConnection(ServerEndpoint& endpoint, NonnullRefPtr socket, int client_id) + : IPC::Connection(endpoint, move(socket)) , m_client_id(client_id) { - ASSERT(m_socket->is_connected()); - ucred creds; - socklen_t creds_size = sizeof(creds); - if (getsockopt(m_socket->fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size) < 0) { - ASSERT_NOT_REACHED(); - } - m_client_pid = creds.pid; - m_socket->on_ready_to_read = [this] { drain_messages_from_client(); }; - - m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); }); + ASSERT(this->socket().is_connected()); + this->socket().on_ready_to_read = [this] { this->drain_messages_from_peer(); }; + this->initialize_peer_info(); } virtual ~ClientConnection() override { } - virtual void may_have_become_unresponsive() { } - virtual void did_become_responsive() { } - - void post_message(const Message& message) - { - // NOTE: If this connection is being shut down, but has not yet been destroyed, - // the socket will be closed. Don't try to send more messages. - if (!m_socket->is_open()) - return; - - auto buffer = message.encode(); - - auto bytes_remaining = buffer.size(); - while (bytes_remaining) { - auto nwritten = write(m_socket->fd(), buffer.data(), buffer.size()); - if (nwritten < 0) { - switch (errno) { - case EPIPE: - dbg() << *this << "::post_message: Disconnected from peer"; - shutdown(); - return; - case EAGAIN: - dbg() << *this << "::post_message: Client buffer overflowed."; - did_misbehave(); - return; - default: - perror("Connection::post_message write"); - shutdown(); - return; - } - } - bytes_remaining -= nwritten; - } - - m_responsiveness_timer->start(); - } - - void drain_messages_from_client() - { - if (!m_socket->is_open()) - return; - - Vector bytes; - for (;;) { - u8 buffer[4096]; - ssize_t nread = recv(m_socket->fd(), buffer, sizeof(buffer), MSG_DONTWAIT); - if (nread == 0 || (nread == -1 && errno == EAGAIN)) { - if (bytes.is_empty()) { - Core::EventLoop::current().post_event(*this, make(client_id())); - return; - } - break; - } - if (nread < 0) { - perror("recv"); - shutdown(); - return; - } - bytes.append(buffer, nread); - } - - if (!bytes.is_empty()) { - m_responsiveness_timer->stop(); - did_become_responsive(); - } - - size_t decoded_bytes = 0; - for (size_t index = 0; index < bytes.size(); index += decoded_bytes) { - auto remaining_bytes = ByteBuffer::wrap(bytes.data() + index, bytes.size() - index); - auto message = Endpoint::decode_message(remaining_bytes, decoded_bytes); - if (!message) { - dbg() << "drain_messages_from_client: Endpoint didn't recognize message"; - did_misbehave(); - return; - } - if (auto response = m_endpoint.handle(*message)) - post_message(*response); - ASSERT(decoded_bytes); - } - } - void did_misbehave() { - dbg() << *this << " (id=" << m_client_id << ", pid=" << m_client_pid << ") misbehaved, disconnecting."; - shutdown(); + dbg() << *this << " (id=" << m_client_id << ", pid=" << client_pid() << ") misbehaved, disconnecting."; + this->shutdown(); } void did_misbehave(const char* message) { - dbg() << *this << " (id=" << m_client_id << ", pid=" << m_client_pid << ") misbehaved (" << message << "), disconnecting."; - shutdown(); - } - - void shutdown() - { - m_socket->close(); - die(); + dbg() << *this << " (id=" << m_client_id << ", pid=" << client_pid() << ") misbehaved (" << message << "), disconnecting."; + this->shutdown(); } int client_id() const { return m_client_id; } - pid_t client_pid() const { return m_client_pid; } - void set_client_pid(pid_t pid) { m_client_pid = pid; } + pid_t client_pid() const { return this->peer_pid(); } + void set_client_pid(pid_t pid) { this->set_peer_pid(pid); } virtual void die() = 0; @@ -213,7 +119,7 @@ protected: int client_id = static_cast(event).client_id(); dbg() << *this << ": Client disconnected: " << client_id; #endif - die(); + this->die(); return; } @@ -221,11 +127,7 @@ protected: } private: - Endpoint& m_endpoint; - NonnullRefPtr m_socket; - RefPtr m_responsiveness_timer; int m_client_id { -1 }; - int m_client_pid { -1 }; }; } diff --git a/Libraries/LibIPC/Connection.h b/Libraries/LibIPC/Connection.h new file mode 100644 index 0000000000..d2df6ad71f --- /dev/null +++ b/Libraries/LibIPC/Connection.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace IPC { + +template +class Connection : public Core::Object { +public: + Connection(LocalEndpoint& local_endpoint, NonnullRefPtr socket) + : m_local_endpoint(local_endpoint) + , m_socket(move(socket)) + , m_notifier(Core::Notifier::construct(m_socket->fd(), Core::Notifier::Read, this)) + { + m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); }); + } + + pid_t peer_pid() const { return m_peer_pid; } + + template + OwnPtr wait_for_specific_message() + { + return wait_for_specific_endpoint_message(); + } + + void post_message(const Message& message) + { + // NOTE: If this connection is being shut down, but has not yet been destroyed, + // the socket will be closed. Don't try to send more messages. + if (!m_socket->is_open()) + return; + + auto buffer = message.encode(); + + auto bytes_remaining = buffer.size(); + while (bytes_remaining) { + auto nwritten = write(m_socket->fd(), buffer.data(), buffer.size()); + if (nwritten < 0) { + switch (errno) { + case EPIPE: + dbg() << *this << "::post_message: Disconnected from peer"; + shutdown(); + return; + case EAGAIN: + dbg() << *this << "::post_message: Peer buffer overflowed"; + shutdown(); + return; + default: + perror("Connection::post_message write"); + shutdown(); + return; + } + } + bytes_remaining -= nwritten; + } + + m_responsiveness_timer->start(); + } + + template + OwnPtr send_sync(Args&&... args) + { + post_message(RequestType(forward(args)...)); + auto response = wait_for_specific_endpoint_message(); + ASSERT(response); + return response; + } + + virtual void may_have_become_unresponsive() { } + virtual void did_become_responsive() { } + + void shutdown() + { + m_socket->close(); + die(); + } + + virtual void die() { } + +protected: + Core::LocalSocket& socket() { return *m_socket; } + Core::Notifier& notifier() { return *m_notifier; } + void set_peer_pid(pid_t pid) { m_peer_pid = pid; } + + template + OwnPtr wait_for_specific_endpoint_message() + { + for (;;) { + // Double check we don't already have the event waiting for us. + // Otherwise we might end up blocked for a while for no reason. + for (size_t i = 0; i < m_unprocessed_messages.size(); ++i) { + auto& message = m_unprocessed_messages[i]; + if (message.endpoint_magic() != Endpoint::static_magic()) + continue; + if (message.message_id() == MessageType::static_message_id()) + return m_unprocessed_messages.take(i).template release_nonnull(); + } + + fd_set rfds; + FD_ZERO(&rfds); + FD_SET(m_socket->fd(), &rfds); + int rc = Core::safe_syscall(select, m_socket->fd() + 1, &rfds, nullptr, nullptr, nullptr); + if (rc < 0) { + perror("select"); + } + ASSERT(rc > 0); + ASSERT(FD_ISSET(m_socket->fd(), &rfds)); + if (!drain_messages_from_peer()) + return nullptr; + } + } + + bool drain_messages_from_peer() + { + Vector bytes; + for (;;) { + u8 buffer[4096]; + ssize_t nread = recv(m_socket->fd(), buffer, sizeof(buffer), MSG_DONTWAIT); + if (nread < 0) { + if (errno == EAGAIN) + break; + perror("recv"); + exit(1); + return false; + } + if (nread == 0) { + dbg() << "EOF on IPC fd"; + if (bytes.is_empty()) { + deferred_invoke([this](auto&) { + dbg() << *this << " Disconnected"; + die(); + }); + } + return false; + } + bytes.append(buffer, nread); + } + + if (!bytes.is_empty()) { + m_responsiveness_timer->stop(); + did_become_responsive(); + } + + size_t decoded_bytes = 0; + for (size_t index = 0; index < bytes.size(); index += decoded_bytes) { + auto remaining_bytes = ByteBuffer::wrap(bytes.data() + index, bytes.size() - index); + if (auto message = LocalEndpoint::decode_message(remaining_bytes, decoded_bytes)) { + m_unprocessed_messages.append(message.release_nonnull()); + } else if (auto message = PeerEndpoint::decode_message(remaining_bytes, decoded_bytes)) { + m_unprocessed_messages.append(message.release_nonnull()); + } else { + ASSERT_NOT_REACHED(); + } + ASSERT(decoded_bytes); + } + + if (!m_unprocessed_messages.is_empty()) { + deferred_invoke([this](auto&) { + handle_messages(); + }); + } + return true; + } + + void handle_messages() + { + auto messages = move(m_unprocessed_messages); + for (auto& message : messages) { + if (message.endpoint_magic() == LocalEndpoint::static_magic()) + if (auto response = m_local_endpoint.handle(message)) + post_message(*response); + } + } + +protected: + void initialize_peer_info() + { + ucred creds; + socklen_t creds_size = sizeof(creds); + if (getsockopt(this->socket().fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size) < 0) { + // FIXME: We should handle this more gracefully. + ASSERT_NOT_REACHED(); + } + m_peer_pid = creds.pid; + } + + LocalEndpoint& m_local_endpoint; + NonnullRefPtr m_socket; + RefPtr m_responsiveness_timer; + + RefPtr m_notifier; + NonnullOwnPtrVector m_unprocessed_messages; + pid_t m_peer_pid { -1 }; +}; + +} diff --git a/Libraries/LibIPC/ServerConnection.h b/Libraries/LibIPC/ServerConnection.h index 1556b309dd..456d29964b 100644 --- a/Libraries/LibIPC/ServerConnection.h +++ b/Libraries/LibIPC/ServerConnection.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -42,159 +43,44 @@ namespace IPC { -template -class ServerConnection : public Core::Object { +template +class ServerConnection : public IPC::Connection { public: - ServerConnection(LocalEndpoint& local_endpoint, const StringView& address) - : m_local_endpoint(local_endpoint) - , m_connection(Core::LocalSocket::construct(this)) - , m_notifier(Core::Notifier::construct(m_connection->fd(), Core::Notifier::Read, this)) + ServerConnection(ClientEndpoint& local_endpoint, const StringView& address) + : Connection(local_endpoint, Core::LocalSocket::construct()) { // We want to rate-limit our clients - m_connection->set_blocking(true); - m_notifier->on_ready_to_read = [this] { - drain_messages_from_server(); - handle_messages(); + this->socket().set_blocking(true); + this->notifier().on_ready_to_read = [this] { + this->drain_messages_from_peer(); + this->handle_messages(); }; - if (!m_connection->connect(Core::SocketAddress::local(address))) { + if (!this->socket().connect(Core::SocketAddress::local(address))) { perror("connect"); ASSERT_NOT_REACHED(); } - ucred creds; - socklen_t creds_size = sizeof(creds); - if (getsockopt(m_connection->fd(), SOL_SOCKET, SO_PEERCRED, &creds, &creds_size) < 0) { - ASSERT_NOT_REACHED(); - } - m_server_pid = creds.pid; + ASSERT(this->socket().is_connected()); - ASSERT(m_connection->is_connected()); + this->initialize_peer_info(); } virtual void handshake() = 0; - pid_t server_pid() const { return m_server_pid; } - void set_server_pid(pid_t pid) { m_server_pid = pid; } + pid_t server_pid() const { return this->peer_pid(); } + void set_server_pid(pid_t pid) { this->set_peer_pid(pid); } void set_my_client_id(int id) { m_my_client_id = id; } int my_client_id() const { return m_my_client_id; } - template - OwnPtr wait_for_specific_message() + virtual void die() override { - return wait_for_specific_endpoint_message(); - } - - bool post_message(const Message& message) - { - auto buffer = message.encode(); - int nwritten = write(m_connection->fd(), buffer.data(), buffer.size()); - if (nwritten < 0) { - perror("write"); - ASSERT_NOT_REACHED(); - return false; - } - ASSERT(static_cast(nwritten) == buffer.size()); - return true; - } - - template - OwnPtr send_sync(Args&&... args) - { - bool success = post_message(RequestType(forward(args)...)); - ASSERT(success); - auto response = wait_for_specific_endpoint_message(); - ASSERT(response); - return response; + // Override this function if you don't want your app to exit if it loses the connection. + exit(0); } private: - template - OwnPtr wait_for_specific_endpoint_message() - { - for (;;) { - // Double check we don't already have the event waiting for us. - // Otherwise we might end up blocked for a while for no reason. - for (size_t i = 0; i < m_unprocessed_messages.size(); ++i) { - auto& message = m_unprocessed_messages[i]; - if (message.endpoint_magic() != Endpoint::static_magic()) - continue; - if (message.message_id() == MessageType::static_message_id()) - return m_unprocessed_messages.take(i).template release_nonnull(); - } - - fd_set rfds; - FD_ZERO(&rfds); - FD_SET(m_connection->fd(), &rfds); - int rc = Core::safe_syscall(select, m_connection->fd() + 1, &rfds, nullptr, nullptr, nullptr); - if (rc < 0) { - perror("select"); - } - ASSERT(rc > 0); - ASSERT(FD_ISSET(m_connection->fd(), &rfds)); - if (!drain_messages_from_server()) - return nullptr; - } - } - - bool drain_messages_from_server() - { - Vector bytes; - for (;;) { - u8 buffer[4096]; - ssize_t nread = recv(m_connection->fd(), buffer, sizeof(buffer), MSG_DONTWAIT); - if (nread < 0) { - if (errno == EAGAIN) - break; - perror("recv"); - exit(1); - return false; - } - if (nread == 0) { - dbg() << "EOF on IPC fd"; - // FIXME: Dying is definitely not always appropriate! - exit(1); - return false; - } - bytes.append(buffer, nread); - } - - size_t decoded_bytes = 0; - for (size_t index = 0; index < bytes.size(); index += decoded_bytes) { - auto remaining_bytes = ByteBuffer::wrap(bytes.data() + index, bytes.size() - index); - if (auto message = LocalEndpoint::decode_message(remaining_bytes, decoded_bytes)) { - m_unprocessed_messages.append(message.release_nonnull()); - } else if (auto message = PeerEndpoint::decode_message(remaining_bytes, decoded_bytes)) { - m_unprocessed_messages.append(message.release_nonnull()); - } else { - ASSERT_NOT_REACHED(); - } - ASSERT(decoded_bytes); - } - - if (!m_unprocessed_messages.is_empty()) { - deferred_invoke([this](auto&) { - handle_messages(); - }); - } - return true; - } - - void handle_messages() - { - auto messages = move(m_unprocessed_messages); - for (auto& message : messages) { - if (message.endpoint_magic() == LocalEndpoint::static_magic()) - m_local_endpoint.handle(message); - } - } - - LocalEndpoint& m_local_endpoint; - RefPtr m_connection; - RefPtr m_notifier; - NonnullOwnPtrVector m_unprocessed_messages; - int m_server_pid { -1 }; int m_my_client_id { -1 }; }; diff --git a/Services/AudioServer/ClientConnection.cpp b/Services/AudioServer/ClientConnection.cpp index db3b150395..7bb5fe8a97 100644 --- a/Services/AudioServer/ClientConnection.cpp +++ b/Services/AudioServer/ClientConnection.cpp @@ -51,7 +51,7 @@ void ClientConnection::for_each(Function callback) } ClientConnection::ClientConnection(NonnullRefPtr client_socket, int client_id, Mixer& mixer) - : IPC::ClientConnection(*this, move(client_socket), client_id) + : IPC::ClientConnection(*this, move(client_socket), client_id) , m_mixer(mixer) { s_connections.set(client_id, *this); diff --git a/Services/AudioServer/ClientConnection.h b/Services/AudioServer/ClientConnection.h index c0ecd4a8da..f08aab49d3 100644 --- a/Services/AudioServer/ClientConnection.h +++ b/Services/AudioServer/ClientConnection.h @@ -27,6 +27,7 @@ #pragma once #include +#include #include #include @@ -39,7 +40,7 @@ namespace AudioServer { class BufferQueue; class Mixer; -class ClientConnection final : public IPC::ClientConnection +class ClientConnection final : public IPC::ClientConnection , public AudioServerEndpoint { C_OBJECT(ClientConnection) public: diff --git a/Services/Clipboard/ClientConnection.cpp b/Services/Clipboard/ClientConnection.cpp index 3e012e5aa5..209a5a699d 100644 --- a/Services/Clipboard/ClientConnection.cpp +++ b/Services/Clipboard/ClientConnection.cpp @@ -42,7 +42,7 @@ void ClientConnection::for_each_client(Function callbac } ClientConnection::ClientConnection(NonnullRefPtr socket, int client_id) - : IPC::ClientConnection(*this, move(socket), client_id) + : IPC::ClientConnection(*this, move(socket), client_id) { s_connections.set(client_id, *this); } diff --git a/Services/Clipboard/ClientConnection.h b/Services/Clipboard/ClientConnection.h index 857d749c29..48794f4f88 100644 --- a/Services/Clipboard/ClientConnection.h +++ b/Services/Clipboard/ClientConnection.h @@ -27,13 +27,16 @@ #pragma once #include +#include #include #include namespace Clipboard { -class ClientConnection final : public IPC::ClientConnection +class ClientConnection final + : public IPC::ClientConnection , public ClipboardServerEndpoint { + C_OBJECT(ClientConnection); public: diff --git a/Services/ImageDecoder/ClientConnection.cpp b/Services/ImageDecoder/ClientConnection.cpp index cea63ce8d9..42df7eb0bc 100644 --- a/Services/ImageDecoder/ClientConnection.cpp +++ b/Services/ImageDecoder/ClientConnection.cpp @@ -37,7 +37,7 @@ namespace ImageDecoder { static HashMap> s_connections; ClientConnection::ClientConnection(NonnullRefPtr socket, int client_id) - : IPC::ClientConnection(*this, move(socket), client_id) + : IPC::ClientConnection(*this, move(socket), client_id) { s_connections.set(client_id, *this); } diff --git a/Services/ImageDecoder/ClientConnection.h b/Services/ImageDecoder/ClientConnection.h index 2021d73682..1447c3b063 100644 --- a/Services/ImageDecoder/ClientConnection.h +++ b/Services/ImageDecoder/ClientConnection.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -35,7 +36,7 @@ namespace ImageDecoder { class ClientConnection final - : public IPC::ClientConnection + : public IPC::ClientConnection , public ImageDecoderServerEndpoint { C_OBJECT(ClientConnection); diff --git a/Services/LaunchServer/ClientConnection.cpp b/Services/LaunchServer/ClientConnection.cpp index 46f716564e..69d1523d2a 100644 --- a/Services/LaunchServer/ClientConnection.cpp +++ b/Services/LaunchServer/ClientConnection.cpp @@ -34,7 +34,7 @@ namespace LaunchServer { static HashMap> s_connections; ClientConnection::ClientConnection(NonnullRefPtr client_socket, int client_id) - : IPC::ClientConnection(*this, move(client_socket), client_id) + : IPC::ClientConnection(*this, move(client_socket), client_id) { s_connections.set(client_id, *this); } diff --git a/Services/LaunchServer/ClientConnection.h b/Services/LaunchServer/ClientConnection.h index f919b328f8..ab3d31bdad 100644 --- a/Services/LaunchServer/ClientConnection.h +++ b/Services/LaunchServer/ClientConnection.h @@ -26,12 +26,13 @@ #pragma once +#include #include #include namespace LaunchServer { -class ClientConnection final : public IPC::ClientConnection +class ClientConnection final : public IPC::ClientConnection , public LaunchServerEndpoint { C_OBJECT(ClientConnection) public: diff --git a/Services/NotificationServer/ClientConnection.cpp b/Services/NotificationServer/ClientConnection.cpp index f90878efe2..9c6cc8051a 100644 --- a/Services/NotificationServer/ClientConnection.cpp +++ b/Services/NotificationServer/ClientConnection.cpp @@ -34,7 +34,7 @@ namespace NotificationServer { static HashMap> s_connections; ClientConnection::ClientConnection(NonnullRefPtr client_socket, int client_id) - : IPC::ClientConnection(*this, move(client_socket), client_id) + : IPC::ClientConnection(*this, move(client_socket), client_id) { s_connections.set(client_id, *this); } diff --git a/Services/NotificationServer/ClientConnection.h b/Services/NotificationServer/ClientConnection.h index 8ea04bbfff..af4e36d0aa 100644 --- a/Services/NotificationServer/ClientConnection.h +++ b/Services/NotificationServer/ClientConnection.h @@ -27,11 +27,12 @@ #pragma once #include +#include #include namespace NotificationServer { -class ClientConnection final : public IPC::ClientConnection +class ClientConnection final : public IPC::ClientConnection , public NotificationServerEndpoint { C_OBJECT(ClientConnection) public: diff --git a/Services/ProtocolServer/ClientConnection.cpp b/Services/ProtocolServer/ClientConnection.cpp index a33baf2973..beaa55c4e1 100644 --- a/Services/ProtocolServer/ClientConnection.cpp +++ b/Services/ProtocolServer/ClientConnection.cpp @@ -36,7 +36,7 @@ namespace ProtocolServer { static HashMap> s_connections; ClientConnection::ClientConnection(NonnullRefPtr socket, int client_id) - : IPC::ClientConnection(*this, move(socket), client_id) + : IPC::ClientConnection(*this, move(socket), client_id) { s_connections.set(client_id, *this); } diff --git a/Services/ProtocolServer/ClientConnection.h b/Services/ProtocolServer/ClientConnection.h index b592c5f29b..4439fdbd87 100644 --- a/Services/ProtocolServer/ClientConnection.h +++ b/Services/ProtocolServer/ClientConnection.h @@ -29,12 +29,13 @@ #include #include #include +#include #include namespace ProtocolServer { class ClientConnection final - : public IPC::ClientConnection + : public IPC::ClientConnection , public ProtocolServerEndpoint { C_OBJECT(ClientConnection); diff --git a/Services/WebContent/ClientConnection.cpp b/Services/WebContent/ClientConnection.cpp index 0a7eacbd85..496f2fec2f 100644 --- a/Services/WebContent/ClientConnection.cpp +++ b/Services/WebContent/ClientConnection.cpp @@ -37,7 +37,7 @@ namespace WebContent { static HashMap> s_connections; ClientConnection::ClientConnection(NonnullRefPtr socket, int client_id) - : IPC::ClientConnection(*this, move(socket), client_id) + : IPC::ClientConnection(*this, move(socket), client_id) , m_page_host(PageHost::create(*this)) { s_connections.set(client_id, *this); diff --git a/Services/WebContent/ClientConnection.h b/Services/WebContent/ClientConnection.h index 22dfca2c51..78301b5842 100644 --- a/Services/WebContent/ClientConnection.h +++ b/Services/WebContent/ClientConnection.h @@ -30,12 +30,13 @@ #include #include #include +#include #include namespace WebContent { class ClientConnection final - : public IPC::ClientConnection + : public IPC::ClientConnection , public WebContentServerEndpoint { C_OBJECT(ClientConnection); diff --git a/Services/WindowServer/ClientConnection.cpp b/Services/WindowServer/ClientConnection.cpp index 7807bf4ee7..6244cdc5ac 100644 --- a/Services/WindowServer/ClientConnection.cpp +++ b/Services/WindowServer/ClientConnection.cpp @@ -78,7 +78,7 @@ ClientConnection* ClientConnection::from_client_id(int client_id) } ClientConnection::ClientConnection(NonnullRefPtr client_socket, int client_id) - : IPC::ClientConnection(*this, move(client_socket), client_id) + : IPC::ClientConnection(*this, move(client_socket), client_id) { if (!s_connections) s_connections = new HashMap>; diff --git a/Services/WindowServer/ClientConnection.h b/Services/WindowServer/ClientConnection.h index 77696a051b..fe1a23afa9 100644 --- a/Services/WindowServer/ClientConnection.h +++ b/Services/WindowServer/ClientConnection.h @@ -35,6 +35,7 @@ #include #include #include +#include #include namespace WindowServer { @@ -45,7 +46,7 @@ class Menu; class MenuBar; class ClientConnection final - : public IPC::ClientConnection + : public IPC::ClientConnection , public WindowServerEndpoint { C_OBJECT(ClientConnection) public: