LibWeb: Protect animation frame callbacks from GC while they execute
Stealing the callbacks from the AnimationFrameCallbackDriver made them no longer safe from GC. Continue to store them on the class until we have finished their execution.
This commit is contained in:
parent
f6991a2955
commit
d188aaf288
Notes:
github-actions[bot]
2024-10-31 14:38:43 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/d188aaf2889 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2083 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/shannonbooth
4 changed files with 23 additions and 2 deletions
Tests/LibWeb/Text
Userland/Libraries/LibWeb/HTML
|
@ -0,0 +1,2 @@
|
|||
Collect garbage
|
||||
PASS! (Didn't crash)
|
14
Tests/LibWeb/Text/input/HTML/requestAnimationFrame-gc.html
Normal file
14
Tests/LibWeb/Text/input/HTML/requestAnimationFrame-gc.html
Normal file
|
@ -0,0 +1,14 @@
|
|||
<script src="../include.js"></script>
|
||||
<script>
|
||||
asyncTest((done) => {
|
||||
requestAnimationFrame(() => {
|
||||
println("Collect garbage");
|
||||
internals.gc();
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
println("PASS! (Didn't crash)");
|
||||
done();
|
||||
});
|
||||
});
|
||||
</script>
|
|
@ -6,6 +6,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <LibWeb/HTML/AnimationFrameCallbackDriver.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ private:
|
|||
WebIDL::UnsignedLong m_animation_frame_callback_identifier { 0 };
|
||||
|
||||
OrderedHashMap<WebIDL::UnsignedLong, Callback> m_callbacks;
|
||||
OrderedHashMap<WebIDL::UnsignedLong, Callback> m_executing_callbacks;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue