From ded337cfec8daa092aa11de597b0148370d1133e Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 9 Aug 2025 13:08:20 -0400 Subject: [PATCH] LibWebView: Gracefully handle RequestServer death This works exactly the same as ImageDecoder death handling. --- Libraries/LibWebView/Application.cpp | 31 ++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Libraries/LibWebView/Application.cpp b/Libraries/LibWebView/Application.cpp index d05902b71ef..1cc72e03923 100644 --- a/Libraries/LibWebView/Application.cpp +++ b/Libraries/LibWebView/Application.cpp @@ -373,9 +373,32 @@ ErrorOr Application::launch_services() ErrorOr Application::launch_request_server() { - // FIXME: Create an abstraction to re-spawn the RequestServer and re-hook up its client hooks to each tab on crash m_request_server_client = TRY(launch_request_server_process()); + m_request_server_client->on_request_server_died = [this]() { + m_request_server_client = nullptr; + + if (Core::EventLoop::current().was_exit_requested()) + return; + + if (auto result = launch_request_server(); result.is_error()) { + warnln("\033[31;1mUnable to launch replacement RequestServer: {}\033[0m", result.error()); + VERIFY_NOT_REACHED(); + } + + auto client_count = WebContentClient::client_count(); + auto request_server_sockets = m_request_server_client->send_sync_but_allow_failure(client_count); + if (!request_server_sockets || request_server_sockets->sockets().is_empty()) { + warnln("\033Failed to connect {} new clients to ImageDecoder\033[0m", client_count); + VERIFY_NOT_REACHED(); + } + + WebContentClient::for_each_client([sockets = request_server_sockets->take_sockets()](WebContentClient& client) mutable { + client.async_connect_to_request_server(sockets.take_last()); + return IterationDecision::Continue; + }); + }; + if (m_browser_options.dns_settings.has_value()) m_settings.set_dns_settings(m_browser_options.dns_settings.value(), true); @@ -538,7 +561,11 @@ void Application::process_did_exit(Process&& process) } break; case ProcessType::RequestServer: - dbgln_if(WEBVIEW_PROCESS_DEBUG, "FIXME: Restart request server"); + if (auto client = process.client(); client.has_value()) { + dbgln_if(WEBVIEW_PROCESS_DEBUG, "Restart request server"); + if (auto on_request_server_died = move(client->on_request_server_died)) + on_request_server_died(); + } break; case ProcessType::WebContent: if (auto client = process.client(); client.has_value()) {