mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
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
|
@ -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…
Reference in a new issue