LibWeb: Do not spin the event loop awaiting text track state changes
Some checks are pending
CI / macOS, arm64, Sanitizer_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers_CI, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer_CI, Clang (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

The text track processing model would previously spin forever waiting
for the track URL to change. It would then recursively invoke itself
to handle the new URL, again entering the spin loop. This meant that
tracks could easily cause event loop hangs.

We now have an observer system to be notified when the track state
changes instead. This lets us exit the processing model and move on.
This commit is contained in:
Timothy Flynn 2025-06-12 08:51:45 -04:00 committed by Tim Flynn
parent 24ac860998
commit de34143a4e
Notes: github-actions[bot] 2025-06-12 16:26:50 +00:00
11 changed files with 182 additions and 17 deletions

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2025, Tim Flynn <trflynn89@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/Realm.h>
#include <LibJS/Runtime/VM.h>
#include <LibWeb/HTML/TextTrackObserver.h>
namespace Web::HTML {
GC_DEFINE_ALLOCATOR(TextTrackObserver);
TextTrackObserver::TextTrackObserver(JS::Realm& realm, TextTrack& text_track)
: Bindings::PlatformObject(realm)
, m_text_track(text_track)
{
m_text_track->register_observer({}, *this);
}
void TextTrackObserver::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_text_track);
visitor.visit(m_track_readiness_observer);
}
void TextTrackObserver::finalize()
{
Base::finalize();
m_text_track->unregister_observer({}, *this);
}
void TextTrackObserver::set_track_readiness_observer(Function<void(TextTrack::ReadinessState)> callback)
{
if (callback)
m_track_readiness_observer = GC::create_function(vm().heap(), move(callback));
else
m_track_readiness_observer = nullptr;
}
}