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 {}; }