Do not capture Trusted<HTMLMediaElement> in ipc::TypedRouterHandler
Describe the bug:
The current implemention for HTMLMediaElement creates cyclic reference dependency between HTMLMediaElement and ipc::TypedRouterHandler so SpiderMonkey is not able to garbage collect HTMLMediaElement due to existed live reference (Trusted<HTMLMediaElement>).
https://github.com/servo/servo/blob/0140b177a36cf4f69da45b46263d4d4768a0d667/components/script/dom/html/htmlmediaelement.rs#L1867
Why it happens?
HTMLMediaElementownsservo_media::Playerwhich ownsIpcSender<PlayerEvent>ipc::ROUTERownsTrusted<HTMLMediaElement>(captured insideipc::TypedRouterHandler) andIpcReceiver<PlayerEvent>
After the latest existed reference in JS will be drop, SM still is able to trace HTMLMediaElement via live reference (Trusted<>) and NOT able drop HTMLMediaElement and reset servo_media::Player which will destroy IpcSender<PlayerEvent>, so later ipc::ROUTER will be notified about it and will release associated ipc::TypedRouterHandler (with Trusted<HTMLMediaElement>).
To Reproduce:
- Run ./mach test-wpt tests/wpt/tests/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm
- Rerun N (10+) times
- Close window
- Check logging with the following patch (multiple HTMLMediaElement will be dropped at once)
impl Drop for HTMLMediaElement {
fn drop(&mut self) {
println!(
"HTMLMediaElement::drop ({:p}) has_player = {:?} video_renderer.refcount = {:?}",
self,
self.player.borrow().is_some(),
Arc::strong_count(&self.video_renderer),
);
}
}
Platform: Ubuntu 22.04