Files
ladybird/Libraries/LibWeb/Worker/WebWorkerClient.cpp
Aliaksandr Kalenik 737691c43a LibWeb: Keep worker startup reachable until script load completes
Fixes flakiness in worker tests that create a Worker or SharedWorker
with a missing script URL and only attach an error handler to it.
Once the test callback returns, nothing keeps the worker rooted from
JavaScript. If GC ran before the WebWorker process reported the
script fetch failure, the Worker/WorkerAgentParent cycle could be
collected and the error event never delivered, leaving the test hung
until timeout.

Hold startup-pending WorkerAgentParents from the outside
EnvironmentSettingsObject and release that edge once the script load
succeeds, fails, or the worker closes. The worker now survives long
enough to deliver its first script-load result.
2026-04-27 18:02:49 +02:00

74 lines
1.9 KiB
C++

/*
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Worker/WebWorkerClient.h>
namespace Web::HTML {
HashTable<WebWorkerClient*> WebWorkerClient::s_all_clients;
void WebWorkerClient::die()
{
// FIXME: Notify WorkerAgent that the worker is dead
}
void WebWorkerClient::did_close_worker()
{
if (on_worker_close)
on_worker_close();
}
void WebWorkerClient::did_finish_loading_worker_script()
{
if (on_worker_script_load_success)
on_worker_script_load_success();
}
void WebWorkerClient::did_fail_loading_worker_script()
{
if (on_worker_script_load_failure)
on_worker_script_load_failure();
}
void WebWorkerClient::did_report_worker_exception(String message, String filename, u32 lineno, u32 colno)
{
if (on_worker_exception)
on_worker_exception(move(message), move(filename), lineno, colno);
}
Messages::WebWorkerClient::DidRequestCookieResponse WebWorkerClient::did_request_cookie(URL::URL url, HTTP::Cookie::Source source)
{
if (on_request_cookie)
return on_request_cookie(url, source);
return HTTP::Cookie::VersionedCookie {};
}
void WebWorkerClient::did_post_broadcast_channel_message(Web::HTML::BroadcastChannelMessage message)
{
if (on_post_broadcast_channel_message)
on_post_broadcast_channel_message(move(message));
}
Messages::WebWorkerClient::RequestWorkerAgentResponse WebWorkerClient::request_worker_agent(Web::Bindings::AgentType worker_type)
{
if (on_request_worker_agent)
return on_request_worker_agent(worker_type);
return { IPC::TransportHandle {}, IPC::TransportHandle {}, IPC::TransportHandle {} };
}
WebWorkerClient::WebWorkerClient(NonnullOwnPtr<IPC::Transport> transport)
: IPC::ConnectionToServer<WebWorkerClientEndpoint, WebWorkerServerEndpoint>(*this, move(transport))
{
s_all_clients.set(this);
}
WebWorkerClient::~WebWorkerClient()
{
s_all_clients.remove(this);
}
}