mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-12 11:09:18 +00:00
RequestServer: Add IPC to create a new client and return the sockets
We'll need this to implement single-instance RS for the Browser.
This commit is contained in:
parent
41667f969d
commit
5e18d157d0
Notes:
sideshowbarker
2024-07-16 23:38:54 +09:00
Author: https://github.com/ADKaster
Commit: 5e18d157d0
Pull-request: https://github.com/SerenityOS/serenity/pull/23945
Reviewed-by: https://github.com/trflynn89 ✅
3 changed files with 52 additions and 3 deletions
|
@ -5,6 +5,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/Badge.h>
|
||||
#include <AK/IDAllocator.h>
|
||||
#include <AK/NonnullOwnPtr.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/Weakable.h>
|
||||
|
@ -21,20 +22,65 @@
|
|||
namespace RequestServer {
|
||||
|
||||
static HashMap<int, RefPtr<ConnectionFromClient>> s_connections;
|
||||
static IDAllocator s_client_ids;
|
||||
|
||||
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket> socket)
|
||||
: IPC::ConnectionFromClient<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), 1)
|
||||
: IPC::ConnectionFromClient<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket), s_client_ids.allocate())
|
||||
{
|
||||
s_connections.set(1, *this);
|
||||
s_connections.set(client_id(), *this);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::die()
|
||||
{
|
||||
s_connections.remove(client_id());
|
||||
auto client_id = this->client_id();
|
||||
s_connections.remove(client_id);
|
||||
s_client_ids.deallocate(client_id);
|
||||
|
||||
if (s_connections.is_empty())
|
||||
Core::EventLoop::current().quit(0);
|
||||
}
|
||||
|
||||
Messages::RequestServer::ConnectNewClientResponse ConnectionFromClient::connect_new_client()
|
||||
{
|
||||
int socket_fds[2] {};
|
||||
if (auto err = Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds); err.is_error()) {
|
||||
dbgln("Failed to create client socketpair: {}", err.error());
|
||||
return { -1, -1 };
|
||||
}
|
||||
|
||||
auto client_socket_or_error = Core::LocalSocket::adopt_fd(socket_fds[0]);
|
||||
if (client_socket_or_error.is_error()) {
|
||||
close(socket_fds[0]);
|
||||
close(socket_fds[1]);
|
||||
dbgln("Failed to adopt client socket: {}", client_socket_or_error.error());
|
||||
return { -1, -1 };
|
||||
}
|
||||
auto client_socket = client_socket_or_error.release_value();
|
||||
// Note: A ref is stored in the static s_connections map
|
||||
auto client = adopt_ref(*new ConnectionFromClient(move(client_socket)));
|
||||
|
||||
int fd_passing_socket_fds[2] {};
|
||||
if (auto err = Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, fd_passing_socket_fds); err.is_error()) {
|
||||
close(socket_fds[1]);
|
||||
dbgln("Failed to create fd-passing socketpair: {}", err.error());
|
||||
return { -1, -1 };
|
||||
}
|
||||
|
||||
auto fd_passing_socket_or_error = Core::LocalSocket::adopt_fd(fd_passing_socket_fds[0]);
|
||||
if (fd_passing_socket_or_error.is_error()) {
|
||||
// socket_fds[0] is already owned by client
|
||||
close(socket_fds[1]);
|
||||
close(fd_passing_socket_fds[0]);
|
||||
close(fd_passing_socket_fds[1]);
|
||||
dbgln("Failed to adopt fd-passing socket: {}", fd_passing_socket_or_error.error());
|
||||
return { -1, -1 };
|
||||
}
|
||||
auto fd_passing_socket = fd_passing_socket_or_error.release_value();
|
||||
client->set_fd_passing_socket(move(fd_passing_socket));
|
||||
|
||||
return { IPC::File(socket_fds[1], IPC::File::CloseAfterSending), IPC::File(fd_passing_socket_fds[1], IPC::File::CloseAfterSending) };
|
||||
}
|
||||
|
||||
Messages::RequestServer::IsSupportedProtocolResponse ConnectionFromClient::is_supported_protocol(ByteString const& protocol)
|
||||
{
|
||||
bool supported = Protocol::find_by_name(protocol.to_lowercase());
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
private:
|
||||
explicit ConnectionFromClient(NonnullOwnPtr<Core::LocalSocket>);
|
||||
|
||||
virtual Messages::RequestServer::ConnectNewClientResponse connect_new_client() override;
|
||||
virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(ByteString const&) override;
|
||||
virtual void start_request(i32 request_id, ByteString const&, URL::URL const&, HashMap<ByteString, ByteString> const&, ByteBuffer const&, Core::ProxyData const&) override;
|
||||
virtual Messages::RequestServer::StopRequestResponse stop_request(i32) override;
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
endpoint RequestServer
|
||||
{
|
||||
connect_new_client() => (IPC::File client_socket, IPC::File client_fd_passing_socket)
|
||||
|
||||
// Test if a specific protocol is supported, e.g "http"
|
||||
is_supported_protocol(ByteString protocol) => (bool supported)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue