mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:52:45 +00:00 
			
		
		
		
	LibIPC: Add IPC::take_over_accepted_client_from_system_server<Client>()
This is an encapsulation of the common work done by all of our
single-client IPC servers on startup:
    1. Create a Core::LocalSocket, taking over an accepted fd.
    2. Create an application-specific ClientConnection object,
       wrapping the socket.
It's not a huge change in terms of lines saved, but I do feel that it
improves expressiveness. :^)
			
			
This commit is contained in:
		
							parent
							
								
									6d0f504822
								
							
						
					
					
						commit
						971b3645ef
					
				
					 18 changed files with 58 additions and 45 deletions
				
			
		|  | @ -14,10 +14,10 @@ namespace LanguageServers { | ||||||
| 
 | 
 | ||||||
| static HashMap<int, RefPtr<ClientConnection>> s_connections; | static HashMap<int, RefPtr<ClientConnection>> s_connections; | ||||||
| 
 | 
 | ||||||
| ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) | ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|     : IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket), client_id) |     : IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint>(*this, move(socket), 1) | ||||||
| { | { | ||||||
|     s_connections.set(client_id, *this); |     s_connections.set(1, *this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClientConnection::~ClientConnection() | ClientConnection::~ClientConnection() | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ namespace LanguageServers { | ||||||
| 
 | 
 | ||||||
| class ClientConnection : public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint> { | class ClientConnection : public IPC::ClientConnection<LanguageClientEndpoint, LanguageServerEndpoint> { | ||||||
| public: | public: | ||||||
|     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); |     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>); | ||||||
|     ~ClientConnection() override; |     ~ClientConnection() override; | ||||||
| 
 | 
 | ||||||
|     virtual void die() override; |     virtual void die() override; | ||||||
|  |  | ||||||
|  | @ -15,8 +15,8 @@ class ClientConnection final : public LanguageServers::ClientConnection { | ||||||
|     C_OBJECT(ClientConnection); |     C_OBJECT(ClientConnection); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) |     ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|         : LanguageServers::ClientConnection(move(socket), client_id) |         : LanguageServers::ClientConnection(move(socket)) | ||||||
|     { |     { | ||||||
|         m_autocomplete_engine = make<CppComprehensionEngine>(m_filedb); |         m_autocomplete_engine = make<CppComprehensionEngine>(m_filedb); | ||||||
|         m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector<GUI::AutocompleteProvider::Declaration>&& declarations) { |         m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector<GUI::AutocompleteProvider::Declaration>&& declarations) { | ||||||
|  |  | ||||||
|  | @ -6,14 +6,12 @@ | ||||||
| 
 | 
 | ||||||
| #include "ClientConnection.h" | #include "ClientConnection.h" | ||||||
| #include "Tests.h" | #include "Tests.h" | ||||||
| #include <AK/LexicalPath.h> |  | ||||||
| #include <LibCore/ArgsParser.h> | #include <LibCore/ArgsParser.h> | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> | #include <LibCore/LocalServer.h> | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| #include <unistd.h> |  | ||||||
| 
 | 
 | ||||||
| static ErrorOr<int> mode_server(); | static ErrorOr<int> mode_server(); | ||||||
| 
 | 
 | ||||||
|  | @ -36,8 +34,7 @@ ErrorOr<int> mode_server() | ||||||
|     Core::EventLoop event_loop; |     Core::EventLoop event_loop; | ||||||
|     TRY(Core::System::pledge("stdio unix recvfd rpath")); |     TRY(Core::System::pledge("stdio unix recvfd rpath")); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<LanguageServers::Cpp::ClientConnection>()); | ||||||
|     (void)IPC::new_client_connection<LanguageServers::Cpp::ClientConnection>(move(socket), 1); |  | ||||||
| 
 | 
 | ||||||
|     TRY(Core::System::pledge("stdio recvfd rpath")); |     TRY(Core::System::pledge("stdio recvfd rpath")); | ||||||
|     TRY(Core::System::unveil("/usr/include", "r")); |     TRY(Core::System::unveil("/usr/include", "r")); | ||||||
|  |  | ||||||
|  | @ -16,8 +16,8 @@ class ClientConnection final : public LanguageServers::ClientConnection { | ||||||
|     C_OBJECT(ClientConnection); |     C_OBJECT(ClientConnection); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) |     ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|         : LanguageServers::ClientConnection(move(socket), client_id) |         : LanguageServers::ClientConnection(move(socket)) | ||||||
|     { |     { | ||||||
|         m_autocomplete_engine = make<ShellComprehensionEngine>(m_filedb); |         m_autocomplete_engine = make<ShellComprehensionEngine>(m_filedb); | ||||||
|         m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector<GUI::AutocompleteProvider::Declaration>&& declarations) { |         m_autocomplete_engine->set_declarations_of_document_callback = [this](const String& filename, Vector<GUI::AutocompleteProvider::Declaration>&& declarations) { | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> | #include <LibCore/LocalServer.h> | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| 
 | 
 | ||||||
| ErrorOr<int> serenity_main(Main::Arguments) | ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|  | @ -16,8 +16,8 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     Core::EventLoop event_loop; |     Core::EventLoop event_loop; | ||||||
|     TRY(Core::System::pledge("stdio unix rpath recvfd")); |     TRY(Core::System::pledge("stdio unix rpath recvfd")); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<LanguageServers::Shell::ClientConnection>()); | ||||||
|     (void)IPC::new_client_connection<LanguageServers::Shell::ClientConnection>(move(socket), 1); | 
 | ||||||
|     TRY(Core::System::pledge("stdio rpath recvfd")); |     TRY(Core::System::pledge("stdio rpath recvfd")); | ||||||
|     TRY(Core::System::unveil("/etc/passwd", "r")); |     TRY(Core::System::unveil("/etc/passwd", "r")); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								Userland/Libraries/LibIPC/SingleServer.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Userland/Libraries/LibIPC/SingleServer.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2021, Andreas Kling <kling@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <LibIPC/ClientConnection.h> | ||||||
|  | 
 | ||||||
|  | namespace IPC { | ||||||
|  | 
 | ||||||
|  | template<typename ClientConnectionType> | ||||||
|  | ErrorOr<NonnullRefPtr<ClientConnectionType>> take_over_accepted_client_from_system_server() | ||||||
|  | { | ||||||
|  |     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); | ||||||
|  |     return IPC::new_client_connection<ClientConnectionType>(move(socket)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -20,10 +20,10 @@ namespace FileSystemAccessServer { | ||||||
| 
 | 
 | ||||||
| static HashMap<int, NonnullRefPtr<ClientConnection>> s_connections; | static HashMap<int, NonnullRefPtr<ClientConnection>> s_connections; | ||||||
| 
 | 
 | ||||||
| ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) | ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|     : IPC::ClientConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket), client_id) |     : IPC::ClientConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket), 1) | ||||||
| { | { | ||||||
|     s_connections.set(client_id, *this); |     s_connections.set(1, *this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClientConnection::~ClientConnection() | ClientConnection::~ClientConnection() | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ public: | ||||||
|     virtual void die() override; |     virtual void die() override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); |     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>); | ||||||
| 
 | 
 | ||||||
|     virtual void request_file_read_only_approved(i32, i32, String const&) override; |     virtual void request_file_read_only_approved(i32, i32, String const&) override; | ||||||
|     virtual void request_file(i32, i32, String const&, Core::OpenMode const&) override; |     virtual void request_file(i32, i32, String const&, Core::OpenMode const&) override; | ||||||
|  |  | ||||||
|  | @ -5,10 +5,9 @@ | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #include <FileSystemAccessServer/ClientConnection.h> | #include <FileSystemAccessServer/ClientConnection.h> | ||||||
| #include <LibCore/LocalServer.h> |  | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibGUI/Application.h> | #include <LibGUI/Application.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| 
 | 
 | ||||||
| ErrorOr<int> serenity_main(Main::Arguments) | ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|  | @ -18,7 +17,6 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     auto app = GUI::Application::construct(0, nullptr); |     auto app = GUI::Application::construct(0, nullptr); | ||||||
|     app->set_quit_when_last_window_deleted(false); |     app->set_quit_when_last_window_deleted(false); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<FileSystemAccessServer::ClientConnection>()); | ||||||
|     (void)IPC::new_client_connection<FileSystemAccessServer::ClientConnection>(move(socket), 1); |  | ||||||
|     return app->exec(); |     return app->exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -6,9 +6,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <ImageDecoder/ClientConnection.h> | #include <ImageDecoder/ClientConnection.h> | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> |  | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| 
 | 
 | ||||||
| ErrorOr<int> serenity_main(Main::Arguments) | ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|  | @ -17,8 +16,8 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     TRY(Core::System::pledge("stdio recvfd sendfd unix")); |     TRY(Core::System::pledge("stdio recvfd sendfd unix")); | ||||||
|     TRY(Core::System::unveil(nullptr, nullptr)); |     TRY(Core::System::unveil(nullptr, nullptr)); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<ImageDecoder::ClientConnection>()); | ||||||
|     auto client = IPC::new_client_connection<ImageDecoder::ClientConnection>(move(socket)); | 
 | ||||||
|     TRY(Core::System::pledge("stdio recvfd sendfd")); |     TRY(Core::System::pledge("stdio recvfd sendfd")); | ||||||
|     return event_loop.exec(); |     return event_loop.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -15,10 +15,10 @@ namespace RequestServer { | ||||||
| 
 | 
 | ||||||
| static HashMap<int, RefPtr<ClientConnection>> s_connections; | static HashMap<int, RefPtr<ClientConnection>> s_connections; | ||||||
| 
 | 
 | ||||||
| ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) | ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|     : IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), client_id) |     : IPC::ClientConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), 1) | ||||||
| { | { | ||||||
|     s_connections.set(client_id, *this); |     s_connections.set(1, *this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClientConnection::~ClientConnection() | ClientConnection::~ClientConnection() | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ public: | ||||||
|     void did_request_certificates(Badge<Request>, Request&); |     void did_request_certificates(Badge<Request>, Request&); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); |     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>); | ||||||
| 
 | 
 | ||||||
|     virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(String const&) override; |     virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(String const&) override; | ||||||
|     virtual Messages::RequestServer::StartRequestResponse start_request(String const&, URL const&, IPC::Dictionary const&, ByteBuffer const&) override; |     virtual Messages::RequestServer::StartRequestResponse start_request(String const&, URL const&, IPC::Dictionary const&, ByteBuffer const&) override; | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> | #include <LibCore/LocalServer.h> | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| #include <LibTLS/Certificate.h> | #include <LibTLS/Certificate.h> | ||||||
| #include <RequestServer/ClientConnection.h> | #include <RequestServer/ClientConnection.h> | ||||||
|  | @ -36,8 +36,8 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     [[maybe_unused]] auto http = make<RequestServer::HttpProtocol>(); |     [[maybe_unused]] auto http = make<RequestServer::HttpProtocol>(); | ||||||
|     [[maybe_unused]] auto https = make<RequestServer::HttpsProtocol>(); |     [[maybe_unused]] auto https = make<RequestServer::HttpsProtocol>(); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<RequestServer::ClientConnection>()); | ||||||
|     (void)IPC::new_client_connection<RequestServer::ClientConnection>(move(socket), 1); | 
 | ||||||
|     auto result = event_loop.exec(); |     auto result = event_loop.exec(); | ||||||
| 
 | 
 | ||||||
|     // FIXME: We exit instead of returning, so that protocol destructors don't get called.
 |     // FIXME: We exit instead of returning, so that protocol destructors don't get called.
 | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> | #include <LibCore/LocalServer.h> | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| #include <WebContent/ClientConnection.h> | #include <WebContent/ClientConnection.h> | ||||||
| 
 | 
 | ||||||
|  | @ -21,7 +21,6 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     TRY(Core::System::unveil("/tmp/portal/websocket", "rw")); |     TRY(Core::System::unveil("/tmp/portal/websocket", "rw")); | ||||||
|     TRY(Core::System::unveil(nullptr, nullptr)); |     TRY(Core::System::unveil(nullptr, nullptr)); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = IPC::take_over_accepted_client_from_system_server<WebContent::ClientConnection>(); | ||||||
|     auto client = IPC::new_client_connection<WebContent::ClientConnection>(move(socket)); |  | ||||||
|     return event_loop.exec(); |     return event_loop.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -13,10 +13,10 @@ namespace WebSocket { | ||||||
| 
 | 
 | ||||||
| static HashMap<int, RefPtr<ClientConnection>> s_connections; | static HashMap<int, RefPtr<ClientConnection>> s_connections; | ||||||
| 
 | 
 | ||||||
| ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket, int client_id) | ClientConnection::ClientConnection(NonnullRefPtr<Core::LocalSocket> socket) | ||||||
|     : IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), client_id) |     : IPC::ClientConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket), 1) | ||||||
| { | { | ||||||
|     s_connections.set(client_id, *this); |     s_connections.set(1, *this); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ClientConnection::~ClientConnection() | ClientConnection::~ClientConnection() | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ public: | ||||||
|     virtual void die() override; |     virtual void die() override; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>, int client_id); |     explicit ClientConnection(NonnullRefPtr<Core::LocalSocket>); | ||||||
| 
 | 
 | ||||||
|     virtual Messages::WebSocketServer::ConnectResponse connect(URL const&, String const&, Vector<String> const&, Vector<String> const&, IPC::Dictionary const&) override; |     virtual Messages::WebSocketServer::ConnectResponse connect(URL const&, String const&, Vector<String> const&, Vector<String> const&, IPC::Dictionary const&) override; | ||||||
|     virtual Messages::WebSocketServer::ReadyStateResponse ready_state(i32) override; |     virtual Messages::WebSocketServer::ReadyStateResponse ready_state(i32) override; | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| #include <LibCore/EventLoop.h> | #include <LibCore/EventLoop.h> | ||||||
| #include <LibCore/LocalServer.h> | #include <LibCore/LocalServer.h> | ||||||
| #include <LibCore/System.h> | #include <LibCore/System.h> | ||||||
| #include <LibIPC/ClientConnection.h> | #include <LibIPC/SingleServer.h> | ||||||
| #include <LibMain/Main.h> | #include <LibMain/Main.h> | ||||||
| #include <LibTLS/Certificate.h> | #include <LibTLS/Certificate.h> | ||||||
| #include <WebSocket/ClientConnection.h> | #include <WebSocket/ClientConnection.h> | ||||||
|  | @ -25,7 +25,7 @@ ErrorOr<int> serenity_main(Main::Arguments) | ||||||
|     TRY(Core::System::unveil("/tmp/portal/lookup", "rw")); |     TRY(Core::System::unveil("/tmp/portal/lookup", "rw")); | ||||||
|     TRY(Core::System::unveil(nullptr, nullptr)); |     TRY(Core::System::unveil(nullptr, nullptr)); | ||||||
| 
 | 
 | ||||||
|     auto socket = TRY(Core::LocalSocket::take_over_accepted_socket_from_system_server()); |     auto client = TRY(IPC::take_over_accepted_client_from_system_server<WebSocket::ClientConnection>()); | ||||||
|     (void)IPC::new_client_connection<WebSocket::ClientConnection>(move(socket), 1); | 
 | ||||||
|     return event_loop.exec(); |     return event_loop.exec(); | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling