mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-11 17:37:33 +02:00
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.
70 lines
2.4 KiB
C++
70 lines
2.4 KiB
C++
/*
|
|
* Copyright (c) 2023, Andrew Kaster <akaster@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/HashTable.h>
|
|
#include <AK/IterationDecision.h>
|
|
#include <AK/Types.h>
|
|
#include <LibHTTP/Cookie/Cookie.h>
|
|
#include <LibIPC/ConnectionToServer.h>
|
|
#include <LibIPC/TransportHandle.h>
|
|
#include <LibWeb/Export.h>
|
|
#include <LibWeb/HTML/BroadcastChannelMessage.h>
|
|
#include <LibWeb/Worker/WebWorkerClientEndpoint.h>
|
|
#include <LibWeb/Worker/WebWorkerServerEndpoint.h>
|
|
|
|
namespace Web::HTML {
|
|
|
|
class WEB_API WebWorkerClient final
|
|
: public IPC::ConnectionToServer<WebWorkerClientEndpoint, WebWorkerServerEndpoint>
|
|
, public WebWorkerClientEndpoint {
|
|
C_OBJECT_ABSTRACT(WebWorkerClient);
|
|
|
|
public:
|
|
template<typename Callback>
|
|
static void for_each_client(Callback callback);
|
|
|
|
explicit WebWorkerClient(NonnullOwnPtr<IPC::Transport>);
|
|
~WebWorkerClient();
|
|
|
|
pid_t pid() const { return m_pid; }
|
|
void set_pid(pid_t pid) { m_pid = pid; }
|
|
|
|
virtual void did_close_worker() override;
|
|
virtual void did_finish_loading_worker_script() override;
|
|
virtual void did_fail_loading_worker_script() override;
|
|
virtual void did_report_worker_exception(String message, String filename, u32 lineno, u32 colno) override;
|
|
virtual Messages::WebWorkerClient::DidRequestCookieResponse did_request_cookie(URL::URL, HTTP::Cookie::Source) override;
|
|
virtual void did_post_broadcast_channel_message(Web::HTML::BroadcastChannelMessage) override;
|
|
virtual Messages::WebWorkerClient::RequestWorkerAgentResponse request_worker_agent(Web::Bindings::AgentType worker_type) override;
|
|
|
|
Function<void()> on_worker_close;
|
|
Function<void()> on_worker_script_load_success;
|
|
Function<void()> on_worker_script_load_failure;
|
|
Function<void(String, String, u32, u32)> on_worker_exception;
|
|
Function<HTTP::Cookie::VersionedCookie(URL::URL const&, HTTP::Cookie::Source)> on_request_cookie;
|
|
Function<void(Web::HTML::BroadcastChannelMessage)> on_post_broadcast_channel_message;
|
|
Function<Messages::WebWorkerClient::RequestWorkerAgentResponse(Web::Bindings::AgentType)> on_request_worker_agent;
|
|
|
|
private:
|
|
virtual void die() override;
|
|
|
|
pid_t m_pid { -1 };
|
|
static HashTable<WebWorkerClient*> s_all_clients;
|
|
};
|
|
|
|
template<typename Callback>
|
|
void WebWorkerClient::for_each_client(Callback callback)
|
|
{
|
|
for (auto* client : s_all_clients) {
|
|
if (callback(*client) == IterationDecision::Break)
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|