mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 04:57:45 +00:00
LibCore+LibIPC+Everywhere: Return Stream::LocalSocket from LocalServer
This change unfortunately cannot be atomically made without a single commit changing everything. Most of the important changes are in LibIPC/Connection.cpp, LibIPC/ServerConnection.cpp and LibCore/LocalServer.cpp. The notable changes are: - IPCCompiler now generates the decode and decode_message functions such that they take a Core::Stream::LocalSocket instead of the socket fd. - IPC::Decoder now uses the receive_fd method of LocalSocket instead of doing system calls directly on the fd. - IPC::ConnectionBase and related classes now use the Stream API functions. - IPC::ServerConnection no longer constructs the socket itself; instead, a convenience macro, IPC_CLIENT_CONNECTION, is used in place of C_OBJECT and will generate a static try_create factory function for the ServerConnection subclass. The subclass is now responsible for passing the socket constructed in this function to its ServerConnection base; the socket is passed as the first argument to the constructor (as a NonnullOwnPtr<Core::Stream::LocalServer>) before any other arguments. - The functionality regarding taking over sockets from SystemServer has been moved to LibIPC/SystemServerTakeover.cpp. The Core::LocalSocket implementation of this functionality hasn't been deleted due to my intention of removing this class in the near future and to reduce noise on this (already quite noisy) PR.
This commit is contained in:
parent
4cad0dd74c
commit
2e1bbcb0fa
94 changed files with 378 additions and 252 deletions
|
@ -14,8 +14,8 @@ namespace Audio {
|
|||
// Real-time audio may be improved with a lower value.
|
||||
static timespec g_enqueue_wait_time { 0, 10'000'000 };
|
||||
|
||||
ClientConnection::ClientConnection()
|
||||
: IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, "/tmp/portal/audio")
|
||||
ClientConnection::ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class Buffer;
|
|||
class ClientConnection final
|
||||
: public IPC::ServerConnection<AudioClientEndpoint, AudioServerEndpoint>
|
||||
, public AudioClientEndpoint {
|
||||
C_OBJECT(ClientConnection)
|
||||
IPC_CLIENT_CONNECTION(ClientConnection, "/tmp/portal/audio")
|
||||
public:
|
||||
void enqueue(Buffer const&);
|
||||
bool try_enqueue(Buffer const&);
|
||||
|
@ -29,7 +29,7 @@ public:
|
|||
Function<void(double volume)> on_client_volume_change;
|
||||
|
||||
private:
|
||||
ClientConnection();
|
||||
ClientConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
virtual void finished_playing_buffer(i32) override;
|
||||
virtual void main_mix_muted_state_changed(bool) override;
|
||||
|
|
|
@ -15,7 +15,7 @@ Client& Client::the()
|
|||
{
|
||||
if (!s_the || !s_the->is_open()) {
|
||||
VERIFY(Core::EventLoop::has_been_instantiated());
|
||||
s_the = Client::construct();
|
||||
s_the = Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
return *s_the;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Config {
|
|||
class Client final
|
||||
: public IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>
|
||||
, public ConfigClientEndpoint {
|
||||
C_OBJECT(Client);
|
||||
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/config")
|
||||
|
||||
public:
|
||||
void pledge_domains(Vector<String> const&);
|
||||
|
@ -39,8 +39,8 @@ public:
|
|||
static Client& the();
|
||||
|
||||
private:
|
||||
explicit Client()
|
||||
: IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, "/tmp/portal/config")
|
||||
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<ConfigClientEndpoint, ConfigServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <LibCore/LocalServer.h>
|
||||
#include <LibCore/LocalSocket.h>
|
||||
#include <LibCore/Notifier.h>
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibCore/System.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
|
@ -80,8 +81,13 @@ void LocalServer::setup_notifier()
|
|||
m_notifier = Notifier::construct(m_fd, Notifier::Event::Read, this);
|
||||
m_notifier->on_ready_to_read = [this] {
|
||||
if (on_accept) {
|
||||
if (auto client_socket = accept())
|
||||
on_accept(client_socket.release_nonnull());
|
||||
auto maybe_client_socket = accept();
|
||||
if (maybe_client_socket.is_error()) {
|
||||
dbgln("LocalServer::on_ready_to_read: Error accepting a connection: {} (FIXME: should propagate!)", maybe_client_socket.error());
|
||||
return;
|
||||
}
|
||||
|
||||
on_accept(maybe_client_socket.release_value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -134,7 +140,7 @@ bool LocalServer::listen(const String& address)
|
|||
return true;
|
||||
}
|
||||
|
||||
RefPtr<LocalSocket> LocalServer::accept()
|
||||
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> LocalServer::accept()
|
||||
{
|
||||
VERIFY(m_listening);
|
||||
sockaddr_un un;
|
||||
|
@ -145,8 +151,7 @@ RefPtr<LocalSocket> LocalServer::accept()
|
|||
int accepted_fd = ::accept(m_fd, (sockaddr*)&un, &un_size);
|
||||
#endif
|
||||
if (accepted_fd < 0) {
|
||||
perror("accept");
|
||||
return nullptr;
|
||||
return Error::from_syscall("accept", -errno);
|
||||
}
|
||||
|
||||
#ifdef AK_OS_MACOS
|
||||
|
@ -155,7 +160,7 @@ RefPtr<LocalSocket> LocalServer::accept()
|
|||
(void)fcntl(accepted_fd, F_SETFD, FD_CLOEXEC);
|
||||
#endif
|
||||
|
||||
return LocalSocket::construct(accepted_fd);
|
||||
return Stream::LocalSocket::adopt_fd(accepted_fd);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <LibCore/Notifier.h>
|
||||
#include <LibCore/Object.h>
|
||||
#include <LibCore/Stream.h>
|
||||
|
||||
namespace Core {
|
||||
|
||||
|
@ -20,9 +21,9 @@ public:
|
|||
bool is_listening() const { return m_listening; }
|
||||
bool listen(const String& address);
|
||||
|
||||
RefPtr<LocalSocket> accept();
|
||||
ErrorOr<NonnullOwnPtr<Stream::LocalSocket>> accept();
|
||||
|
||||
Function<void(NonnullRefPtr<Core::LocalSocket>)> on_accept;
|
||||
Function<void(NonnullOwnPtr<Stream::LocalSocket>)> on_accept;
|
||||
|
||||
private:
|
||||
explicit LocalServer(Object* parent = nullptr);
|
||||
|
|
|
@ -36,17 +36,17 @@ auto Launcher::Details::from_details_str(const String& details_str) -> NonnullRe
|
|||
class LaunchServerConnection final
|
||||
: public IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>
|
||||
, public LaunchClientEndpoint {
|
||||
C_OBJECT(LaunchServerConnection)
|
||||
IPC_CLIENT_CONNECTION(LaunchServerConnection, "/tmp/portal/launch")
|
||||
private:
|
||||
LaunchServerConnection()
|
||||
: IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, "/tmp/portal/launch")
|
||||
LaunchServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static LaunchServerConnection& connection()
|
||||
{
|
||||
static auto connection = LaunchServerConnection::construct();
|
||||
static auto connection = LaunchServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ static RefPtr<Client> s_the = nullptr;
|
|||
Client& Client::the()
|
||||
{
|
||||
if (!s_the || !s_the->is_open())
|
||||
s_the = Client::construct();
|
||||
s_the = Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ struct Result {
|
|||
class Client final
|
||||
: public IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>
|
||||
, public FileSystemAccessClientEndpoint {
|
||||
C_OBJECT(Client)
|
||||
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/filesystemaccess")
|
||||
|
||||
public:
|
||||
Result request_file_read_only_approved(i32 parent_window_id, String const& path);
|
||||
|
@ -38,8 +38,8 @@ protected:
|
|||
void die() override;
|
||||
|
||||
private:
|
||||
explicit Client()
|
||||
: IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, "/tmp/portal/filesystemaccess")
|
||||
explicit Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<FileSystemAccessClientEndpoint, FileSystemAccessServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ namespace GUI {
|
|||
class ClipboardServerConnection final
|
||||
: public IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>
|
||||
, public ClipboardClientEndpoint {
|
||||
C_OBJECT(ClipboardServerConnection);
|
||||
IPC_CLIENT_CONNECTION(ClipboardServerConnection, "/tmp/portal/clipboard")
|
||||
|
||||
private:
|
||||
ClipboardServerConnection()
|
||||
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, "/tmp/portal/clipboard")
|
||||
ClipboardServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<ClipboardClientEndpoint, ClipboardServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
static ClipboardServerConnection* s_connection;
|
||||
static RefPtr<ClipboardServerConnection> s_connection;
|
||||
|
||||
static ClipboardServerConnection& connection()
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ static ClipboardServerConnection& connection()
|
|||
|
||||
void Clipboard::initialize(Badge<Application>)
|
||||
{
|
||||
s_connection = &ClipboardServerConnection::construct().leak_ref();
|
||||
s_connection = ClipboardServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
}
|
||||
|
||||
Clipboard& Clipboard::the()
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace GUI {
|
|||
class NotificationServerConnection final
|
||||
: public IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>
|
||||
, public NotificationClientEndpoint {
|
||||
C_OBJECT(NotificationServerConnection)
|
||||
IPC_CLIENT_CONNECTION(NotificationServerConnection, "/tmp/portal/notify")
|
||||
|
||||
friend class Notification;
|
||||
|
||||
|
@ -25,8 +25,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
explicit NotificationServerConnection(Notification* notification)
|
||||
: IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, "/tmp/portal/notify")
|
||||
explicit NotificationServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket, Notification* notification)
|
||||
: IPC::ServerConnection<NotificationClientEndpoint, NotificationServerEndpoint>(*this, move(socket))
|
||||
, m_notification(notification)
|
||||
{
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void Notification::show()
|
|||
{
|
||||
VERIFY(!m_shown && !m_destroyed);
|
||||
auto icon = m_icon ? m_icon->to_shareable_bitmap() : Gfx::ShareableBitmap();
|
||||
m_connection = NotificationServerConnection::construct(this);
|
||||
m_connection = NotificationServerConnection::try_create(this).release_value_but_fixme_should_propagate_errors();
|
||||
m_connection->show_notification(m_text, m_title, icon);
|
||||
m_shown = true;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@ namespace GUI {
|
|||
|
||||
WindowManagerServerConnection& WindowManagerServerConnection::the()
|
||||
{
|
||||
static WindowManagerServerConnection* s_connection = nullptr;
|
||||
static RefPtr<WindowManagerServerConnection> s_connection = nullptr;
|
||||
if (!s_connection)
|
||||
s_connection = new WindowManagerServerConnection;
|
||||
s_connection = WindowManagerServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return *s_connection;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,13 +16,14 @@ namespace GUI {
|
|||
class WindowManagerServerConnection final
|
||||
: public IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>
|
||||
, public WindowManagerClientEndpoint {
|
||||
C_OBJECT(WindowManagerServerConnection)
|
||||
IPC_CLIENT_CONNECTION(WindowManagerServerConnection, "/tmp/portal/wm")
|
||||
|
||||
public:
|
||||
static WindowManagerServerConnection& the();
|
||||
|
||||
private:
|
||||
WindowManagerServerConnection()
|
||||
: IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, "/tmp/portal/wm")
|
||||
WindowManagerServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<WindowManagerClientEndpoint, WindowManagerServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ namespace GUI {
|
|||
|
||||
WindowServerConnection& WindowServerConnection::the()
|
||||
{
|
||||
static WindowServerConnection* s_connection = nullptr;
|
||||
static RefPtr<WindowServerConnection> s_connection = nullptr;
|
||||
if (!s_connection)
|
||||
s_connection = new WindowServerConnection;
|
||||
s_connection = WindowServerConnection::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return *s_connection;
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,8 @@ static void set_system_theme_from_anonymous_buffer(Core::AnonymousBuffer buffer)
|
|||
Application::the()->set_system_palette(buffer);
|
||||
}
|
||||
|
||||
WindowServerConnection::WindowServerConnection()
|
||||
: IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, "/tmp/portal/window")
|
||||
WindowServerConnection::WindowServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
// NOTE: WindowServer automatically sends a "fast_greet" message to us when we connect.
|
||||
// All we have to do is wait for it to arrive. This avoids a round-trip during application startup.
|
||||
|
|
|
@ -16,13 +16,13 @@ namespace GUI {
|
|||
class WindowServerConnection final
|
||||
: public IPC::ServerConnection<WindowClientEndpoint, WindowServerEndpoint>
|
||||
, public WindowClientEndpoint {
|
||||
C_OBJECT(WindowServerConnection)
|
||||
IPC_CLIENT_CONNECTION(WindowServerConnection, "/tmp/portal/window")
|
||||
public:
|
||||
static WindowServerConnection& the();
|
||||
i32 expose_client_id() { return m_client_id; }
|
||||
|
||||
private:
|
||||
WindowServerConnection();
|
||||
WindowServerConnection(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
virtual void fast_greet(Vector<Gfx::IntRect> const&, u32, u32, u32, Core::AnonymousBuffer const&, String const&, String const&, i32) override;
|
||||
virtual void paint(i32, Gfx::IntSize const&, Vector<Gfx::IntRect> const&) override;
|
||||
|
|
|
@ -4,6 +4,7 @@ set(SOURCES
|
|||
Encoder.cpp
|
||||
Message.cpp
|
||||
Stub.cpp
|
||||
SystemServerTakeover.cpp
|
||||
)
|
||||
|
||||
serenity_lib(LibIPC ipc)
|
||||
|
|
|
@ -24,12 +24,12 @@ public:
|
|||
using ServerStub = typename ServerEndpoint::Stub;
|
||||
using IPCProxy = typename ClientEndpoint::template Proxy<ServerEndpoint>;
|
||||
|
||||
ClientConnection(ServerStub& stub, NonnullRefPtr<Core::LocalSocket> socket, int client_id)
|
||||
ClientConnection(ServerStub& stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, int client_id)
|
||||
: IPC::Connection<ServerEndpoint, ClientEndpoint>(stub, move(socket))
|
||||
, ClientEndpoint::template Proxy<ServerEndpoint>(*this, {})
|
||||
, m_client_id(client_id)
|
||||
{
|
||||
VERIFY(this->socket().is_connected());
|
||||
VERIFY(this->socket().is_open());
|
||||
this->socket().on_ready_to_read = [this] {
|
||||
// FIXME: Do something about errors.
|
||||
(void)this->drain_messages_from_peer();
|
||||
|
|
|
@ -11,10 +11,9 @@
|
|||
|
||||
namespace IPC {
|
||||
|
||||
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullRefPtr<Core::LocalSocket> socket, u32 local_endpoint_magic)
|
||||
ConnectionBase::ConnectionBase(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket, u32 local_endpoint_magic)
|
||||
: m_local_stub(local_stub)
|
||||
, m_socket(move(socket))
|
||||
, m_notifier(Core::Notifier::construct(m_socket->fd(), Core::Notifier::Read, this))
|
||||
, m_local_endpoint_magic(local_endpoint_magic)
|
||||
{
|
||||
m_responsiveness_timer = Core::Timer::create_single_shot(3000, [this] { may_have_become_unresponsive(); });
|
||||
|
@ -42,7 +41,7 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
|||
|
||||
#ifdef __serenity__
|
||||
for (auto& fd : buffer.fds) {
|
||||
if (auto result = Core::System::sendfd(m_socket->fd(), fd.value()); result.is_error()) {
|
||||
if (auto result = m_socket->send_fd(fd.value()); result.is_error()) {
|
||||
dbgln("{}", result.error());
|
||||
shutdown();
|
||||
return result;
|
||||
|
@ -53,23 +52,29 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
|||
warnln("fd passing is not supported on this platform, sorry :(");
|
||||
#endif
|
||||
|
||||
size_t total_nwritten = 0;
|
||||
while (total_nwritten < buffer.data.size()) {
|
||||
auto nwritten = write(m_socket->fd(), buffer.data.data() + total_nwritten, buffer.data.size() - total_nwritten);
|
||||
if (nwritten < 0) {
|
||||
switch (errno) {
|
||||
case EPIPE:
|
||||
shutdown();
|
||||
return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
|
||||
case EAGAIN:
|
||||
shutdown();
|
||||
return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
|
||||
default:
|
||||
shutdown();
|
||||
return Error::from_syscall("IPC::Connection::post_message write"sv, -errno);
|
||||
ReadonlyBytes bytes_to_write { buffer.data.span() };
|
||||
while (!bytes_to_write.is_empty()) {
|
||||
auto maybe_nwritten = m_socket->write(bytes_to_write);
|
||||
if (maybe_nwritten.is_error()) {
|
||||
auto error = maybe_nwritten.release_error();
|
||||
if (error.is_errno()) {
|
||||
switch (error.code()) {
|
||||
case EPIPE:
|
||||
shutdown();
|
||||
return Error::from_string_literal("IPC::Connection::post_message: Disconnected from peer"sv);
|
||||
case EAGAIN:
|
||||
shutdown();
|
||||
return Error::from_string_literal("IPC::Connection::post_message: Peer buffer overflowed"sv);
|
||||
default:
|
||||
shutdown();
|
||||
return Error::from_syscall("IPC::Connection::post_message write"sv, -error.code());
|
||||
}
|
||||
} else {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
total_nwritten += nwritten;
|
||||
|
||||
bytes_to_write = bytes_to_write.slice(maybe_nwritten.value());
|
||||
}
|
||||
|
||||
m_responsiveness_timer->start();
|
||||
|
@ -78,7 +83,6 @@ ErrorOr<void> ConnectionBase::post_message(MessageBuffer buffer)
|
|||
|
||||
void ConnectionBase::shutdown()
|
||||
{
|
||||
m_notifier->close();
|
||||
m_socket->close();
|
||||
die();
|
||||
}
|
||||
|
@ -99,21 +103,14 @@ void ConnectionBase::handle_messages()
|
|||
|
||||
void ConnectionBase::wait_for_socket_to_become_readable()
|
||||
{
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(m_socket->fd(), &read_fds);
|
||||
for (;;) {
|
||||
if (auto rc = select(m_socket->fd() + 1, &read_fds, nullptr, nullptr, nullptr); rc < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror("wait_for_specific_endpoint_message: select");
|
||||
VERIFY_NOT_REACHED();
|
||||
} else {
|
||||
VERIFY(rc > 0);
|
||||
VERIFY(FD_ISSET(m_socket->fd(), &read_fds));
|
||||
break;
|
||||
}
|
||||
auto maybe_did_become_readable = m_socket->can_read_without_blocking(-1);
|
||||
if (maybe_did_become_readable.is_error()) {
|
||||
dbgln("ConnectionBase::wait_for_socket_to_become_readable: {}", maybe_did_become_readable.error());
|
||||
warnln("ConnectionBase::wait_for_socket_to_become_readable: {}", maybe_did_become_readable.error());
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
VERIFY(maybe_did_become_readable.value());
|
||||
}
|
||||
|
||||
ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without_blocking()
|
||||
|
@ -125,15 +122,21 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
|||
m_unprocessed_bytes.clear();
|
||||
}
|
||||
|
||||
u8 buffer[4096];
|
||||
while (m_socket->is_open()) {
|
||||
u8 buffer[4096];
|
||||
ssize_t nread = recv(m_socket->fd(), buffer, sizeof(buffer), MSG_DONTWAIT);
|
||||
if (nread < 0) {
|
||||
if (errno == EAGAIN)
|
||||
auto maybe_nread = m_socket->read_without_waiting({ buffer, 4096 });
|
||||
if (maybe_nread.is_error()) {
|
||||
auto error = maybe_nread.release_error();
|
||||
if (error.is_syscall() && error.code() == EAGAIN) {
|
||||
break;
|
||||
perror("recv");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
dbgln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||
warnln("ConnectionBase::read_as_much_as_possible_from_socket_without_blocking: {}", error);
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
auto nread = maybe_nread.release_value();
|
||||
if (nread == 0) {
|
||||
if (bytes.is_empty()) {
|
||||
deferred_invoke([this] { shutdown(); });
|
||||
|
@ -141,6 +144,7 @@ ErrorOr<Vector<u8>> ConnectionBase::read_as_much_as_possible_from_socket_without
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
bytes.append(buffer, nread);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include <AK/Try.h>
|
||||
#include <LibCore/Event.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/LocalSocket.h>
|
||||
#include <LibCore/Notifier.h>
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibCore/Timer.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibIPC/Message.h>
|
||||
|
@ -39,9 +39,9 @@ public:
|
|||
virtual void die() { }
|
||||
|
||||
protected:
|
||||
explicit ConnectionBase(IPC::Stub&, NonnullRefPtr<Core::LocalSocket>, u32 local_endpoint_magic);
|
||||
explicit ConnectionBase(IPC::Stub&, NonnullOwnPtr<Core::Stream::LocalSocket>, u32 local_endpoint_magic);
|
||||
|
||||
Core::LocalSocket& socket() { return *m_socket; }
|
||||
Core::Stream::LocalSocket& socket() { return *m_socket; }
|
||||
|
||||
virtual void may_have_become_unresponsive() { }
|
||||
virtual void did_become_responsive() { }
|
||||
|
@ -57,10 +57,9 @@ protected:
|
|||
|
||||
IPC::Stub& m_local_stub;
|
||||
|
||||
NonnullRefPtr<Core::LocalSocket> m_socket;
|
||||
NonnullOwnPtr<Core::Stream::LocalSocket> m_socket;
|
||||
RefPtr<Core::Timer> m_responsiveness_timer;
|
||||
|
||||
RefPtr<Core::Notifier> m_notifier;
|
||||
NonnullOwnPtrVector<Message> m_unprocessed_messages;
|
||||
ByteBuffer m_unprocessed_bytes;
|
||||
|
||||
|
@ -70,10 +69,10 @@ protected:
|
|||
template<typename LocalEndpoint, typename PeerEndpoint>
|
||||
class Connection : public ConnectionBase {
|
||||
public:
|
||||
Connection(IPC::Stub& local_stub, NonnullRefPtr<Core::LocalSocket> socket)
|
||||
Connection(IPC::Stub& local_stub, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: ConnectionBase(local_stub, move(socket), LocalEndpoint::static_magic())
|
||||
{
|
||||
m_notifier->on_ready_to_read = [this] {
|
||||
m_socket->on_ready_to_read = [this] {
|
||||
NonnullRefPtr protect = *this;
|
||||
// FIXME: Do something about errors.
|
||||
(void)drain_messages_from_peer();
|
||||
|
@ -122,9 +121,9 @@ protected:
|
|||
break;
|
||||
index += sizeof(message_size);
|
||||
auto remaining_bytes = ReadonlyBytes { bytes.data() + index, message_size };
|
||||
if (auto message = LocalEndpoint::decode_message(remaining_bytes, m_socket->fd())) {
|
||||
if (auto message = LocalEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||
m_unprocessed_messages.append(message.release_nonnull());
|
||||
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, m_socket->fd())) {
|
||||
} else if (auto message = PeerEndpoint::decode_message(remaining_bytes, *m_socket)) {
|
||||
m_unprocessed_messages.append(message.release_nonnull());
|
||||
} else {
|
||||
dbgln("Failed to parse a message");
|
||||
|
|
|
@ -162,14 +162,9 @@ ErrorOr<void> Decoder::decode(Dictionary& dictionary)
|
|||
|
||||
ErrorOr<void> Decoder::decode([[maybe_unused]] File& file)
|
||||
{
|
||||
#ifdef __serenity__
|
||||
int fd = TRY(Core::System::recvfd(m_sockfd, O_CLOEXEC));
|
||||
int fd = TRY(m_socket.receive_fd(O_CLOEXEC));
|
||||
file = File(fd, File::ConstructWithReceivedFileDescriptor);
|
||||
return {};
|
||||
#else
|
||||
[[maybe_unused]] auto fd = m_sockfd;
|
||||
return Error::from_string_literal("File descriptor passing not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
ErrorOr<void> decode(Decoder& decoder, Core::AnonymousBuffer& buffer)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <AK/NumericLimits.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibIPC/Message.h>
|
||||
|
||||
|
@ -25,9 +26,9 @@ inline ErrorOr<void> decode(Decoder&, T&)
|
|||
|
||||
class Decoder {
|
||||
public:
|
||||
Decoder(InputMemoryStream& stream, int sockfd)
|
||||
Decoder(InputMemoryStream& stream, Core::Stream::LocalSocket& socket)
|
||||
: m_stream(stream)
|
||||
, m_sockfd(sockfd)
|
||||
, m_socket(socket)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -115,7 +116,7 @@ public:
|
|||
|
||||
private:
|
||||
InputMemoryStream& m_stream;
|
||||
int m_sockfd { -1 };
|
||||
Core::Stream::LocalSocket& m_socket;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,10 +6,24 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/Stream.h>
|
||||
#include <LibIPC/Connection.h>
|
||||
|
||||
namespace IPC {
|
||||
|
||||
#define IPC_CLIENT_CONNECTION(klass, socket_path) \
|
||||
C_OBJECT_ABSTRACT(klass) \
|
||||
public: \
|
||||
template<typename Klass = klass, class... Args> \
|
||||
static ErrorOr<NonnullRefPtr<klass>> try_create(Args&&... args) \
|
||||
{ \
|
||||
auto socket = TRY(Core::Stream::LocalSocket::connect(socket_path)); \
|
||||
/* We want to rate-limit our clients */ \
|
||||
TRY(socket->set_blocking(true)); \
|
||||
\
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) Klass(move(socket), forward<Args>(args)...)); \
|
||||
}
|
||||
|
||||
template<typename ClientEndpoint, typename ServerEndpoint>
|
||||
class ServerConnection : public IPC::Connection<ClientEndpoint, ServerEndpoint>
|
||||
, public ClientEndpoint::Stub
|
||||
|
@ -18,19 +32,10 @@ public:
|
|||
using ClientStub = typename ClientEndpoint::Stub;
|
||||
using IPCProxy = typename ServerEndpoint::template Proxy<ClientEndpoint>;
|
||||
|
||||
ServerConnection(ClientStub& local_endpoint, StringView address)
|
||||
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, Core::LocalSocket::construct())
|
||||
ServerConnection(ClientStub& local_endpoint, NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: Connection<ClientEndpoint, ServerEndpoint>(local_endpoint, move(socket))
|
||||
, ServerEndpoint::template Proxy<ClientEndpoint>(*this, {})
|
||||
{
|
||||
// We want to rate-limit our clients
|
||||
this->socket().set_blocking(true);
|
||||
|
||||
if (!this->socket().connect(Core::SocketAddress::local(address))) {
|
||||
perror("connect");
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
VERIFY(this->socket().is_connected());
|
||||
}
|
||||
|
||||
virtual void die() override
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/System.h>
|
||||
#include <LibIPC/ClientConnection.h>
|
||||
#include <LibIPC/SystemServerTakeover.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());
|
||||
auto socket = TRY(take_over_accepted_socket_from_system_server());
|
||||
return IPC::new_client_connection<ClientConnectionType>(move(socket));
|
||||
}
|
||||
|
||||
|
|
65
Userland/Libraries/LibIPC/SystemServerTakeover.cpp
Normal file
65
Userland/Libraries/LibIPC/SystemServerTakeover.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "SystemServerTakeover.h"
|
||||
#include <LibCore/System.h>
|
||||
|
||||
HashMap<String, int> s_overtaken_sockets {};
|
||||
bool s_overtaken_sockets_parsed { false };
|
||||
|
||||
void parse_sockets_from_system_server()
|
||||
{
|
||||
VERIFY(!s_overtaken_sockets_parsed);
|
||||
|
||||
constexpr auto socket_takeover = "SOCKET_TAKEOVER";
|
||||
const char* sockets = getenv(socket_takeover);
|
||||
if (!sockets) {
|
||||
s_overtaken_sockets_parsed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& socket : StringView(sockets).split_view(' ')) {
|
||||
auto params = socket.split_view(':');
|
||||
s_overtaken_sockets.set(params[0].to_string(), strtol(params[1].to_string().characters(), nullptr, 10));
|
||||
}
|
||||
|
||||
s_overtaken_sockets_parsed = true;
|
||||
// We wouldn't want our children to think we're passing
|
||||
// them a socket either, so unset the env variable.
|
||||
unsetenv(socket_takeover);
|
||||
}
|
||||
|
||||
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_accepted_socket_from_system_server(String const& socket_path)
|
||||
{
|
||||
if (!s_overtaken_sockets_parsed)
|
||||
parse_sockets_from_system_server();
|
||||
|
||||
int fd;
|
||||
if (socket_path.is_null()) {
|
||||
// We want the first (and only) socket.
|
||||
VERIFY(s_overtaken_sockets.size() == 1);
|
||||
fd = s_overtaken_sockets.begin()->value;
|
||||
} else {
|
||||
auto it = s_overtaken_sockets.find(socket_path);
|
||||
if (it == s_overtaken_sockets.end())
|
||||
return Error::from_string_literal("Non-existent socket requested"sv);
|
||||
fd = it->value;
|
||||
}
|
||||
|
||||
// Sanity check: it has to be a socket.
|
||||
auto stat = TRY(Core::System::fstat(fd));
|
||||
|
||||
if (!S_ISSOCK(stat.st_mode))
|
||||
return Error::from_string_literal("The fd we got from SystemServer is not a socket"sv);
|
||||
|
||||
auto socket = TRY(Core::Stream::LocalSocket::adopt_fd(fd));
|
||||
// It had to be !CLOEXEC for obvious reasons, but we
|
||||
// don't need it to be !CLOEXEC anymore, so set the
|
||||
// CLOEXEC flag now.
|
||||
TRY(socket->set_close_on_exec(true));
|
||||
|
||||
return socket;
|
||||
}
|
12
Userland/Libraries/LibIPC/SystemServerTakeover.h
Normal file
12
Userland/Libraries/LibIPC/SystemServerTakeover.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibCore/Stream.h>
|
||||
|
||||
void parse_sockets_from_system_server();
|
||||
ErrorOr<NonnullOwnPtr<Core::Stream::LocalSocket>> take_over_accepted_socket_from_system_server(String const& socket_path = {});
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
namespace ImageDecoderClient {
|
||||
|
||||
Client::Client()
|
||||
: IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, "/tmp/portal/image")
|
||||
Client::Client(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ struct DecodedImage {
|
|||
class Client final
|
||||
: public IPC::ServerConnection<ImageDecoderClientEndpoint, ImageDecoderServerEndpoint>
|
||||
, public ImageDecoderClientEndpoint {
|
||||
C_OBJECT(Client);
|
||||
IPC_CLIENT_CONNECTION(Client, "/tmp/portal/image");
|
||||
|
||||
public:
|
||||
Optional<DecodedImage> decode_image(ReadonlyBytes);
|
||||
|
@ -35,7 +35,7 @@ public:
|
|||
Function<void()> on_death;
|
||||
|
||||
private:
|
||||
Client();
|
||||
Client(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
virtual void die() override;
|
||||
};
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
namespace Protocol {
|
||||
|
||||
RequestClient::RequestClient()
|
||||
: IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, "/tmp/portal/request")
|
||||
RequestClient::RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class Request;
|
|||
class RequestClient final
|
||||
: public IPC::ServerConnection<RequestClientEndpoint, RequestServerEndpoint>
|
||||
, public RequestClientEndpoint {
|
||||
C_OBJECT(RequestClient);
|
||||
IPC_CLIENT_CONNECTION(RequestClient, "/tmp/portal/request")
|
||||
|
||||
public:
|
||||
template<typename RequestHashMapTraits = Traits<String>>
|
||||
|
@ -30,7 +30,7 @@ public:
|
|||
bool set_certificate(Badge<Request>, Request&, String, String);
|
||||
|
||||
private:
|
||||
RequestClient();
|
||||
RequestClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
virtual void request_progress(i32, Optional<u32> const&, u32) override;
|
||||
virtual void request_finished(i32, bool, u32) override;
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
namespace Protocol {
|
||||
|
||||
WebSocketClient::WebSocketClient()
|
||||
: IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, "/tmp/portal/websocket")
|
||||
WebSocketClient::WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class WebSocket;
|
|||
class WebSocketClient final
|
||||
: public IPC::ServerConnection<WebSocketClientEndpoint, WebSocketServerEndpoint>
|
||||
, public WebSocketClientEndpoint {
|
||||
C_OBJECT(WebSocketClient);
|
||||
IPC_CLIENT_CONNECTION(WebSocketClient, "/tmp/portal/websocket")
|
||||
|
||||
public:
|
||||
RefPtr<WebSocket> connect(const URL&, const String& origin = {}, const Vector<String>& protocols = {}, const Vector<String>& extensions = {}, const HashMap<String, String>& request_headers = {});
|
||||
|
@ -29,7 +29,7 @@ public:
|
|||
bool set_certificate(Badge<WebSocket>, WebSocket&, String, String);
|
||||
|
||||
private:
|
||||
WebSocketClient();
|
||||
WebSocketClient(NonnullOwnPtr<Core::Stream::LocalSocket>);
|
||||
|
||||
virtual void connected(i32) override;
|
||||
virtual void received(i32, bool, ByteBuffer const&) override;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace SQL {
|
|||
class SQLClient
|
||||
: public IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>
|
||||
, public SQLClientEndpoint {
|
||||
C_OBJECT(SQLClient);
|
||||
IPC_CLIENT_CONNECTION(SQLClient, "/tmp/portal/sql")
|
||||
virtual ~SQLClient();
|
||||
|
||||
Function<void(int, String const&)> on_connected;
|
||||
|
@ -27,8 +27,8 @@ class SQLClient
|
|||
Function<void(int, int)> on_results_exhausted;
|
||||
|
||||
private:
|
||||
SQLClient()
|
||||
: IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, "/tmp/portal/sql")
|
||||
SQLClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
|
||||
: IPC::ServerConnection<SQLClientEndpoint, SQLServerEndpoint>(*this, move(socket))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -29,14 +29,20 @@ namespace Web::HTML {
|
|||
|
||||
WebSocketClientManager& WebSocketClientManager::the()
|
||||
{
|
||||
static WebSocketClientManager* s_the;
|
||||
static RefPtr<WebSocketClientManager> s_the;
|
||||
if (!s_the)
|
||||
s_the = &WebSocketClientManager::construct().leak_ref();
|
||||
s_the = WebSocketClientManager::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
WebSocketClientManager::WebSocketClientManager()
|
||||
: m_websocket_client(Protocol::WebSocketClient::construct())
|
||||
ErrorOr<NonnullRefPtr<WebSocketClientManager>> WebSocketClientManager::try_create()
|
||||
{
|
||||
auto websocket_client = TRY(Protocol::WebSocketClient::try_create());
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) WebSocketClientManager(move(websocket_client)));
|
||||
}
|
||||
|
||||
WebSocketClientManager::WebSocketClientManager(NonnullRefPtr<Protocol::WebSocketClient> websocket_client)
|
||||
: m_websocket_client(move(websocket_client))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -31,14 +31,16 @@ class WebSocket;
|
|||
namespace Web::HTML {
|
||||
|
||||
class WebSocketClientManager : public Core::Object {
|
||||
C_OBJECT(WebSocketClientManager)
|
||||
C_OBJECT_ABSTRACT(WebSocketClientManager)
|
||||
public:
|
||||
static WebSocketClientManager& the();
|
||||
|
||||
RefPtr<Protocol::WebSocket> connect(const AK::URL&);
|
||||
|
||||
private:
|
||||
WebSocketClientManager();
|
||||
static ErrorOr<NonnullRefPtr<WebSocketClientManager>> try_create();
|
||||
WebSocketClientManager(NonnullRefPtr<Protocol::WebSocketClient>);
|
||||
|
||||
RefPtr<Protocol::WebSocketClient> m_websocket_client;
|
||||
};
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ ImageDecoderClient::Client& image_decoder_client()
|
|||
{
|
||||
static RefPtr<ImageDecoderClient::Client> image_decoder_client;
|
||||
if (!image_decoder_client) {
|
||||
image_decoder_client = ImageDecoderClient::Client::construct();
|
||||
image_decoder_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
image_decoder_client->on_death = [&] {
|
||||
image_decoder_client = nullptr;
|
||||
};
|
||||
|
|
|
@ -21,14 +21,21 @@ namespace Web {
|
|||
|
||||
ResourceLoader& ResourceLoader::the()
|
||||
{
|
||||
static ResourceLoader* s_the;
|
||||
static RefPtr<ResourceLoader> s_the;
|
||||
if (!s_the)
|
||||
s_the = &ResourceLoader::construct().leak_ref();
|
||||
s_the = ResourceLoader::try_create().release_value_but_fixme_should_propagate_errors();
|
||||
return *s_the;
|
||||
}
|
||||
|
||||
ResourceLoader::ResourceLoader()
|
||||
: m_protocol_client(Protocol::RequestClient::construct())
|
||||
ErrorOr<NonnullRefPtr<ResourceLoader>> ResourceLoader::try_create()
|
||||
{
|
||||
|
||||
auto protocol_client = TRY(Protocol::RequestClient::try_create());
|
||||
return adopt_nonnull_ref_or_enomem(new (nothrow) ResourceLoader(move(protocol_client)));
|
||||
}
|
||||
|
||||
ResourceLoader::ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client)
|
||||
: m_protocol_client(move(protocol_client))
|
||||
, m_user_agent(default_user_agent)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace Web {
|
|||
constexpr auto default_user_agent = "Mozilla/4.0 (SerenityOS; " CPU_STRING ") LibWeb+LibJS (Not KHTML, nor Gecko) LibWeb";
|
||||
|
||||
class ResourceLoader : public Core::Object {
|
||||
C_OBJECT(ResourceLoader)
|
||||
C_OBJECT_ABSTRACT(ResourceLoader)
|
||||
public:
|
||||
static ResourceLoader& the();
|
||||
|
||||
|
@ -52,7 +52,9 @@ public:
|
|||
void clear_cache();
|
||||
|
||||
private:
|
||||
ResourceLoader();
|
||||
ResourceLoader(NonnullRefPtr<Protocol::RequestClient> protocol_client);
|
||||
static ErrorOr<NonnullRefPtr<ResourceLoader>> try_create();
|
||||
|
||||
static bool is_port_blocked(int port);
|
||||
|
||||
int m_pending_loads { 0 };
|
||||
|
|
|
@ -62,7 +62,7 @@ void OutOfProcessWebView::create_client()
|
|||
{
|
||||
m_client_state = {};
|
||||
|
||||
m_client_state.client = WebContentClient::construct(*this);
|
||||
m_client_state.client = WebContentClient::try_create(*this).release_value_but_fixme_should_propagate_errors();
|
||||
m_client_state.client->on_web_content_process_crash = [this] {
|
||||
deferred_invoke([this] {
|
||||
handle_web_content_process_crash();
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
|
||||
namespace Web {
|
||||
|
||||
WebContentClient::WebContentClient(OutOfProcessWebView& view)
|
||||
: IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, "/tmp/portal/webcontent")
|
||||
WebContentClient::WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket> socket, OutOfProcessWebView& view)
|
||||
: IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(socket))
|
||||
, m_view(view)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -19,13 +19,13 @@ class OutOfProcessWebView;
|
|||
class WebContentClient final
|
||||
: public IPC::ServerConnection<WebContentClientEndpoint, WebContentServerEndpoint>
|
||||
, public WebContentClientEndpoint {
|
||||
C_OBJECT(WebContentClient);
|
||||
IPC_CLIENT_CONNECTION(WebContentClient, "/tmp/portal/webcontent");
|
||||
|
||||
public:
|
||||
Function<void()> on_web_content_process_crash;
|
||||
|
||||
private:
|
||||
WebContentClient(OutOfProcessWebView&);
|
||||
WebContentClient(NonnullOwnPtr<Core::Stream::LocalSocket>, OutOfProcessWebView&);
|
||||
|
||||
virtual void die() override;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue