diff --git a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp
index db1de05cc49..4d4361dd22c 100644
--- a/Libraries/LibWeb/HTML/WorkerAgentParent.cpp
+++ b/Libraries/LibWeb/HTML/WorkerAgentParent.cpp
@@ -49,12 +49,15 @@ void WorkerAgentParent::initialize(JS::Realm& realm)
// NOTE: This blocking IPC call may launch another process.
// If spinning the event loop for this can cause other javascript to execute, we're in trouble.
- auto handle = Bindings::principal_host_defined_page(realm).client().request_worker_agent(m_agent_type);
+ auto response = Bindings::principal_host_defined_page(realm).client().request_worker_agent(m_agent_type);
- auto transport = MUST(handle.create_transport());
+ auto transport = MUST(response.worker_handle.create_transport());
m_worker_ipc = make_ref_counted(move(transport));
setup_worker_ipc_callbacks(realm);
+ m_worker_ipc->async_connect_to_request_server(move(response.request_server_handle));
+ m_worker_ipc->async_connect_to_image_decoder(move(response.image_decoder_handle));
+
auto serialized_outside_settings = m_outside_settings->serialize();
m_worker_ipc->async_start_worker(m_url, m_worker_options.type, m_worker_options.credentials, m_worker_options.name, move(data_holder), serialized_outside_settings, m_agent_type);
@@ -67,9 +70,10 @@ void WorkerAgentParent::setup_worker_ipc_callbacks(JS::Realm& realm)
auto& client = Bindings::principal_host_defined_page(realm).client();
return client.page_did_request_cookie(url, source);
};
- m_worker_ipc->on_request_worker_agent = [realm = GC::RawRef { realm }](Web::Bindings::AgentType worker_type) {
+ m_worker_ipc->on_request_worker_agent = [realm = GC::RawRef { realm }](Web::Bindings::AgentType worker_type) -> Messages::WebWorkerClient::RequestWorkerAgentResponse {
auto& client = Bindings::principal_host_defined_page(realm).client();
- return client.request_worker_agent(worker_type);
+ auto response = client.request_worker_agent(worker_type);
+ return { move(response.worker_handle), move(response.request_server_handle), move(response.image_decoder_handle) };
};
m_worker_ipc->on_worker_script_load_failure = [self = GC::Weak { *this }]() {
if (!self)
diff --git a/Libraries/LibWeb/Page/Page.h b/Libraries/LibWeb/Page/Page.h
index e4cb521703b..b63c69e3dc3 100644
--- a/Libraries/LibWeb/Page/Page.h
+++ b/Libraries/LibWeb/Page/Page.h
@@ -440,7 +440,12 @@ public:
virtual void page_did_receive_network_response_body([[maybe_unused]] u64 request_id, [[maybe_unused]] ReadonlyBytes data) { }
virtual void page_did_finish_network_request([[maybe_unused]] u64 request_id, [[maybe_unused]] u64 body_size, [[maybe_unused]] Requests::RequestTimingInfo const& timing_info, [[maybe_unused]] Optional const& network_error) { }
- virtual IPC::TransportHandle request_worker_agent([[maybe_unused]] Web::Bindings::AgentType worker_type) { return IPC::TransportHandle {}; }
+ struct WorkerAgentResponse {
+ IPC::TransportHandle worker_handle;
+ IPC::TransportHandle request_server_handle;
+ IPC::TransportHandle image_decoder_handle;
+ };
+ virtual WorkerAgentResponse request_worker_agent([[maybe_unused]] Web::Bindings::AgentType worker_type) { return {}; }
virtual void page_did_mutate_dom([[maybe_unused]] FlyString const& type, [[maybe_unused]] DOM::Node const& target, [[maybe_unused]] DOM::NodeList& added_nodes, [[maybe_unused]] DOM::NodeList& removed_nodes, [[maybe_unused]] GC::Ptr previous_sibling, [[maybe_unused]] GC::Ptr next_sibling, [[maybe_unused]] Optional const& attribute_name) { }
diff --git a/Libraries/LibWeb/Worker/WebWorkerClient.cpp b/Libraries/LibWeb/Worker/WebWorkerClient.cpp
index 9132edd960c..f7443770683 100644
--- a/Libraries/LibWeb/Worker/WebWorkerClient.cpp
+++ b/Libraries/LibWeb/Worker/WebWorkerClient.cpp
@@ -37,7 +37,7 @@ Messages::WebWorkerClient::RequestWorkerAgentResponse WebWorkerClient::request_w
{
if (on_request_worker_agent)
return on_request_worker_agent(worker_type);
- return IPC::TransportHandle {};
+ return { IPC::TransportHandle {}, IPC::TransportHandle {}, IPC::TransportHandle {} };
}
WebWorkerClient::WebWorkerClient(NonnullOwnPtr transport)
diff --git a/Libraries/LibWeb/Worker/WebWorkerClient.h b/Libraries/LibWeb/Worker/WebWorkerClient.h
index b5ddb29ff6a..c07e7dd9176 100644
--- a/Libraries/LibWeb/Worker/WebWorkerClient.h
+++ b/Libraries/LibWeb/Worker/WebWorkerClient.h
@@ -31,7 +31,7 @@ public:
Function on_worker_close;
Function on_worker_script_load_failure;
Function on_request_cookie;
- Function on_request_worker_agent;
+ Function on_request_worker_agent;
IPC::TransportHandle clone_transport();
diff --git a/Libraries/LibWeb/Worker/WebWorkerClient.ipc b/Libraries/LibWeb/Worker/WebWorkerClient.ipc
index fb2ee28822d..a4c087338da 100644
--- a/Libraries/LibWeb/Worker/WebWorkerClient.ipc
+++ b/Libraries/LibWeb/Worker/WebWorkerClient.ipc
@@ -7,5 +7,5 @@ endpoint WebWorkerClient {
did_close_worker() =|
did_fail_loading_worker_script() =|
did_request_cookie(URL::URL url, HTTP::Cookie::Source source) => (HTTP::Cookie::VersionedCookie cookie)
- request_worker_agent(Web::Bindings::AgentType worker_type) => (IPC::TransportHandle handle)
+ request_worker_agent(Web::Bindings::AgentType worker_type) => (IPC::TransportHandle handle, IPC::TransportHandle request_server_handle, IPC::TransportHandle image_decoder_handle)
}
diff --git a/Libraries/LibWeb/Worker/WebWorkerServer.ipc b/Libraries/LibWeb/Worker/WebWorkerServer.ipc
index 4a732d94a96..792da629092 100644
--- a/Libraries/LibWeb/Worker/WebWorkerServer.ipc
+++ b/Libraries/LibWeb/Worker/WebWorkerServer.ipc
@@ -1,5 +1,6 @@
#include
#include
+#include
#include
#include
#include
@@ -7,6 +8,9 @@
endpoint WebWorkerServer {
+ connect_to_request_server(IPC::TransportHandle handle) =|
+ connect_to_image_decoder(IPC::TransportHandle handle) =|
+
start_worker(URL::URL url,
Web::Bindings::WorkerType type,
Web::Bindings::RequestCredentials credentials,
diff --git a/Libraries/LibWebView/HelperProcess.cpp b/Libraries/LibWebView/HelperProcess.cpp
index 548777037e7..4b416a1871e 100644
--- a/Libraries/LibWebView/HelperProcess.cpp
+++ b/Libraries/LibWebView/HelperProcess.cpp
@@ -177,14 +177,6 @@ ErrorOr> launch_web_worker_process(Web
if (web_content_options.enable_http_memory_cache == WebView::EnableMemoryHTTPCache::Yes)
arguments.append("--enable-http-memory-cache"sv);
- auto request_server_handle = TRY(connect_new_request_server_client());
- arguments.append("--request-server-socket"sv);
- arguments.append(ByteString::number(request_server_handle.fd()));
-
- auto image_decoder_handle = TRY(connect_new_image_decoder_client());
- arguments.append("--image-decoder-socket"sv);
- arguments.append(ByteString::number(image_decoder_handle.fd()));
-
arguments.append("--type"sv);
switch (type) {
case Web::Bindings::AgentType::DedicatedWorker:
diff --git a/Libraries/LibWebView/WebContentClient.cpp b/Libraries/LibWebView/WebContentClient.cpp
index d7976f3e4de..3bfd99fc26c 100644
--- a/Libraries/LibWebView/WebContentClient.cpp
+++ b/Libraries/LibWebView/WebContentClient.cpp
@@ -788,11 +788,13 @@ void WebContentClient::did_allocate_backing_stores(u64 page_id, i32 front_bitmap
Messages::WebContentClient::RequestWorkerAgentResponse WebContentClient::request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type)
{
if (auto view = view_for_page_id(page_id); view.has_value()) {
+ auto request_server_handle = MUST(connect_new_request_server_client());
+ auto image_decoder_handle = MUST(connect_new_image_decoder_client());
auto worker_client = MUST(WebView::launch_web_worker_process(worker_type));
- return worker_client->clone_transport();
+ return { worker_client->clone_transport(), move(request_server_handle), move(image_decoder_handle) };
}
- return IPC::TransportHandle {};
+ return { IPC::TransportHandle {}, IPC::TransportHandle {}, IPC::TransportHandle {} };
}
Optional WebContentClient::view_for_page_id(u64 page_id, SourceLocation location)
diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp
index 3437703267b..432fda56877 100644
--- a/Services/WebContent/PageClient.cpp
+++ b/Services/WebContent/PageClient.cpp
@@ -731,7 +731,7 @@ void PageClient::page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::Shar
client().async_did_allocate_backing_stores(m_id, front_bitmap_id, front_bitmap, back_bitmap_id, back_bitmap);
}
-IPC::TransportHandle PageClient::request_worker_agent(Web::Bindings::AgentType type)
+Web::PageClient::WorkerAgentResponse PageClient::request_worker_agent(Web::Bindings::AgentType type)
{
auto response = client().send_sync_but_allow_failure(m_id, type);
if (!response) {
@@ -739,7 +739,7 @@ IPC::TransportHandle PageClient::request_worker_agent(Web::Bindings::AgentType t
exit(0);
}
- return response->take_handle();
+ return { response->take_handle(), response->take_request_server_handle(), response->take_image_decoder_handle() };
}
void PageClient::page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr, GC::Ptr, Optional const& attribute_name)
diff --git a/Services/WebContent/PageClient.h b/Services/WebContent/PageClient.h
index 511d8817741..8b004c42b29 100644
--- a/Services/WebContent/PageClient.h
+++ b/Services/WebContent/PageClient.h
@@ -188,7 +188,7 @@ private:
virtual void page_did_request_clipboard_entries(u64 request_id) override;
virtual void page_did_change_audio_play_state(Web::HTML::AudioPlayState) override;
virtual void page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::ShareableBitmap front_bitmap, i32 back_bitmap_id, Gfx::ShareableBitmap back_bitmap) override;
- virtual IPC::TransportHandle request_worker_agent(Web::Bindings::AgentType) override;
+ virtual WorkerAgentResponse request_worker_agent(Web::Bindings::AgentType) override;
virtual void page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr previous_sibling, GC::Ptr next_sibling, Optional const& attribute_name) override;
virtual void page_did_paint(Gfx::IntRect const& content_rect, i32 bitmap_id) override;
virtual void page_did_take_screenshot(Gfx::ShareableBitmap const& screenshot) override;
diff --git a/Services/WebContent/WebContentClient.ipc b/Services/WebContent/WebContentClient.ipc
index bc24cc26c37..e346529b026 100644
--- a/Services/WebContent/WebContentClient.ipc
+++ b/Services/WebContent/WebContentClient.ipc
@@ -135,5 +135,5 @@ endpoint WebContentClient
did_find_in_page(u64 page_id, size_t current_match_index, Optional total_match_count) =|
- request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) => (IPC::TransportHandle handle) // FIXME: Add required attributes to select a SharedWorker Agent
+ request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) => (IPC::TransportHandle handle, IPC::TransportHandle request_server_handle, IPC::TransportHandle image_decoder_handle) // FIXME: Add required attributes to select a SharedWorker Agent
}
diff --git a/Services/WebWorker/ConnectionFromClient.cpp b/Services/WebWorker/ConnectionFromClient.cpp
index cd3a15afd4b..f07b1978a7d 100644
--- a/Services/WebWorker/ConnectionFromClient.cpp
+++ b/Services/WebWorker/ConnectionFromClient.cpp
@@ -11,6 +11,18 @@
namespace WebWorker {
+void ConnectionFromClient::connect_to_request_server(IPC::TransportHandle handle)
+{
+ if (on_request_server_connection)
+ on_request_server_connection(handle);
+}
+
+void ConnectionFromClient::connect_to_image_decoder(IPC::TransportHandle handle)
+{
+ if (on_image_decoder_connection)
+ on_image_decoder_connection(handle);
+}
+
void ConnectionFromClient::close_worker()
{
async_did_close_worker();
diff --git a/Services/WebWorker/ConnectionFromClient.h b/Services/WebWorker/ConnectionFromClient.h
index 857e68bb809..573567c5ab5 100644
--- a/Services/WebWorker/ConnectionFromClient.h
+++ b/Services/WebWorker/ConnectionFromClient.h
@@ -35,12 +35,17 @@ public:
PageHost& page_host() { return *m_page_host; }
PageHost const& page_host() const { return *m_page_host; }
+ Function on_request_server_connection;
+ Function on_image_decoder_connection;
+
private:
explicit ConnectionFromClient(NonnullOwnPtr);
Web::Page& page();
Web::Page const& page() const;
+ virtual void connect_to_request_server(IPC::TransportHandle handle) override;
+ virtual void connect_to_image_decoder(IPC::TransportHandle handle) override;
virtual void start_worker(URL::URL url, Web::Bindings::WorkerType type, Web::Bindings::RequestCredentials credentials, String name, Web::HTML::TransferDataEncoder, Web::HTML::SerializedEnvironmentSettingsObject, Web::Bindings::AgentType) override;
virtual void handle_file_return(i32 error, Optional file, i32 request_id) override;
diff --git a/Services/WebWorker/PageHost.cpp b/Services/WebWorker/PageHost.cpp
index 67a34782558..d41492b5b4d 100644
--- a/Services/WebWorker/PageHost.cpp
+++ b/Services/WebWorker/PageHost.cpp
@@ -97,9 +97,10 @@ void PageHost::request_file(Web::FileRequest request)
m_client.request_file(move(request));
}
-IPC::TransportHandle PageHost::request_worker_agent(Web::Bindings::AgentType worker_type)
+Web::PageClient::WorkerAgentResponse PageHost::request_worker_agent(Web::Bindings::AgentType worker_type)
{
- return m_client.request_worker_agent(worker_type);
+ auto response = m_client.request_worker_agent(worker_type);
+ return { response.take_handle(), response.take_request_server_handle(), response.take_image_decoder_handle() };
}
void PageHost::did_fail_loading_worker_script()
diff --git a/Services/WebWorker/PageHost.h b/Services/WebWorker/PageHost.h
index 8ac9777df6a..ac6c8f0c50a 100644
--- a/Services/WebWorker/PageHost.h
+++ b/Services/WebWorker/PageHost.h
@@ -38,7 +38,7 @@ public:
virtual size_t screen_count() const override { return 1; }
virtual HTTP::Cookie::VersionedCookie page_did_request_cookie(URL::URL const&, HTTP::Cookie::Source) override;
virtual void request_file(Web::FileRequest) override;
- virtual IPC::TransportHandle request_worker_agent(Web::Bindings::AgentType) override;
+ virtual WorkerAgentResponse request_worker_agent(Web::Bindings::AgentType) override;
virtual Web::DisplayListPlayerType display_list_player_type() const override { VERIFY_NOT_REACHED(); }
virtual bool is_headless() const override { VERIFY_NOT_REACHED(); }
virtual Queue& input_event_queue() override { VERIFY_NOT_REACHED(); }
diff --git a/Services/WebWorker/main.cpp b/Services/WebWorker/main.cpp
index cf5e9e73363..990957dff4e 100644
--- a/Services/WebWorker/main.cpp
+++ b/Services/WebWorker/main.cpp
@@ -11,7 +11,10 @@
#include
#include
#include
+#include
+#include
#include
+#include
#include
#include
#include
@@ -19,15 +22,14 @@
#include
#include
#include
-#include
#include
#include
#include
#include
-static ErrorOr initialize_image_decoder(int image_decoder_socket);
-static ErrorOr initialize_resource_loader(GC::Heap&, int request_server_socket);
+static ErrorOr connect_to_resource_loader(GC::Heap& heap, IPC::TransportHandle const& handle);
+static ErrorOr connect_to_image_decoder(IPC::TransportHandle const& handle);
static ErrorOr agent_type_from_string(StringView type)
{
@@ -45,8 +47,6 @@ ErrorOr ladybird_main(Main::Arguments arguments)
{
AK::set_rich_debug_enabled(true);
- int request_server_socket { -1 };
- int image_decoder_socket { -1 };
StringView serenity_resource_root;
StringView worker_type_string;
Vector certificates;
@@ -56,8 +56,6 @@ ErrorOr ladybird_main(Main::Arguments arguments)
bool file_origins_are_tuple_origins = false;
Core::ArgsParser args_parser;
- args_parser.add_option(request_server_socket, "File descriptor of the request server socket", "request-server-socket", 's', "request-server-socket");
- args_parser.add_option(image_decoder_socket, "File descriptor of the socket for the ImageDecoder connection", "image-decoder-socket", 'i', "image_decoder_socket");
args_parser.add_option(serenity_resource_root, "Absolute path to directory for serenity resources", "serenity-resource-root", 'r', "serenity-resource-root");
args_parser.add_option(certificates, "Path to a certificate file", "certificate", 'C', "certificate");
args_parser.add_option(expose_experimental_interfaces, "Expose experimental IDL interfaces", "expose-experimental-interfaces");
@@ -85,8 +83,6 @@ ErrorOr ladybird_main(Main::Arguments arguments)
OPENSSL_TRY(OSSL_set_max_threads(nullptr, Core::System::hardware_concurrency()));
- TRY(initialize_image_decoder(image_decoder_socket));
-
Web::HTML::UniversalGlobalScopeMixin::set_experimental_interfaces_exposed(expose_experimental_interfaces);
Web::Platform::EventLoopPlugin::install(*new Web::Platform::EventLoopPlugin);
@@ -95,50 +91,47 @@ ErrorOr ladybird_main(Main::Arguments arguments)
Web::Bindings::initialize_main_thread_vm(worker_type);
- TRY(initialize_resource_loader(Web::Bindings::main_thread_vm().heap(), request_server_socket));
-
auto client = TRY(IPC::take_over_accepted_client_from_system_server());
+ auto& heap = Web::Bindings::main_thread_vm().heap();
+ client->on_request_server_connection = [&heap](auto const& handle) {
+ if (auto result = connect_to_resource_loader(heap, handle); result.is_error())
+ dbgln("Failed to connect to resource loader: {}", result.error());
+ };
+ client->on_image_decoder_connection = [](auto const& handle) {
+ if (auto result = connect_to_image_decoder(handle); result.is_error())
+ dbgln("Failed to connect to image decoder: {}", result.error());
+ };
+
return event_loop.exec();
}
-static ErrorOr initialize_image_decoder(int image_decoder_socket)
+static ErrorOr connect_to_resource_loader(GC::Heap& heap, IPC::TransportHandle const& handle)
{
-#if !defined(AK_OS_WINDOWS)
- static_assert(IsSame, "Need to handle other IPC transports here");
-#else
- static_assert(IsSame, "Need to handle other IPC transports here");
-#endif
- auto socket = TRY(Core::LocalSocket::adopt_fd(image_decoder_socket));
- TRY(socket->set_blocking(true));
-
- auto new_client = TRY(try_make_ref_counted(make(move(socket))));
-#ifdef AK_OS_WINDOWS
- auto response = new_client->send_sync(Core::System::getpid());
- new_client->transport().set_peer_pid(response->peer_pid());
-#endif
-
- Web::Platform::ImageCodecPlugin::install(*new WebView::ImageCodecPlugin(move(new_client)));
-
- return {};
-}
-
-static ErrorOr initialize_resource_loader(GC::Heap& heap, int request_server_socket)
-{
-#if !defined(AK_OS_WINDOWS)
- static_assert(IsSame, "Need to handle other IPC transports here");
-#else
- static_assert(IsSame, "Need to handle other IPC transports here");
-#endif
- auto socket = TRY(Core::LocalSocket::adopt_fd(request_server_socket));
- TRY(socket->set_blocking(true));
-
- auto request_client = TRY(try_make_ref_counted(make(move(socket))));
+ auto transport = TRY(handle.create_transport());
+ auto request_client = TRY(try_make_ref_counted(move(transport)));
#ifdef AK_OS_WINDOWS
auto response = request_client->send_sync(Core::System::getpid());
request_client->transport().set_peer_pid(response->peer_pid());
#endif
- Web::ResourceLoader::initialize(heap, move(request_client));
-
+ if (Web::ResourceLoader::is_initialized())
+ Web::ResourceLoader::the().set_client(move(request_client));
+ else
+ Web::ResourceLoader::initialize(heap, move(request_client));
+ return {};
+}
+
+static ErrorOr connect_to_image_decoder(IPC::TransportHandle const& handle)
+{
+ auto transport = TRY(handle.create_transport());
+ auto new_client = TRY(try_make_ref_counted(move(transport)));
+#ifdef AK_OS_WINDOWS
+ auto response = new_client->send_sync(Core::System::getpid());
+ new_client->transport().set_peer_pid(response->peer_pid());
+#endif
+ if (Web::Platform::ImageCodecPlugin::is_initialized())
+ static_cast(Web::Platform::ImageCodecPlugin::the()).set_client(move(new_client));
+ else
+ Web::Platform::ImageCodecPlugin::install(*new WebView::ImageCodecPlugin(move(new_client)));
return {};
}