diff --git a/Tests/LibWeb/Text/expected/HTML/requestAnimationFrame-gc.txt b/Tests/LibWeb/Text/expected/HTML/requestAnimationFrame-gc.txt new file mode 100644 index 00000000000..c6eef0ccec7 --- /dev/null +++ b/Tests/LibWeb/Text/expected/HTML/requestAnimationFrame-gc.txt @@ -0,0 +1,2 @@ +Collect garbage +PASS! (Didn't crash) diff --git a/Tests/LibWeb/Text/input/HTML/requestAnimationFrame-gc.html b/Tests/LibWeb/Text/input/HTML/requestAnimationFrame-gc.html new file mode 100644 index 00000000000..0a1b63423bf --- /dev/null +++ b/Tests/LibWeb/Text/input/HTML/requestAnimationFrame-gc.html @@ -0,0 +1,14 @@ + + diff --git a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.cpp b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.cpp index f0765c9164a..c21f866ca9a 100644 --- a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.cpp +++ b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.cpp @@ -6,6 +6,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include namespace Web::HTML { @@ -16,6 +17,7 @@ void AnimationFrameCallbackDriver::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_callbacks); + visitor.visit(m_executing_callbacks); } WebIDL::UnsignedLong AnimationFrameCallbackDriver::add(Callback handler) @@ -37,8 +39,10 @@ bool AnimationFrameCallbackDriver::has_callbacks() const void AnimationFrameCallbackDriver::run(double now) { - auto taken_callbacks = move(m_callbacks); - for (auto& [id, callback] : taken_callbacks) + AK::ScopeGuard guard { [&]() { m_executing_callbacks.clear(); } }; + m_executing_callbacks = move(m_callbacks); + + for (auto& [id, callback] : m_executing_callbacks) callback->function()(now); } diff --git a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h index 24161a5d324..85f2e4e144e 100644 --- a/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h +++ b/Userland/Libraries/LibWeb/HTML/AnimationFrameCallbackDriver.h @@ -34,6 +34,7 @@ private: WebIDL::UnsignedLong m_animation_frame_callback_identifier { 0 }; OrderedHashMap m_callbacks; + OrderedHashMap m_executing_callbacks; }; }