servo icon indicating copy to clipboard operation
servo copied to clipboard

Do not capture Trusted<HTMLMediaElement> in ipc::TypedRouterHandler

Open tharkum opened this issue 2 months ago • 0 comments

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?

  1. HTMLMediaElement owns servo_media::Player which owns IpcSender<PlayerEvent>
  2. ipc::ROUTER owns Trusted<HTMLMediaElement> (captured inside ipc::TypedRouterHandler) and IpcReceiver<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:

  1. Run ./mach test-wpt tests/wpt/tests/html/semantics/embedded-content/the-video-element/intrinsic_sizes.htm
  2. Rerun N (10+) times
  3. Close window
  4. 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

tharkum avatar Oct 28 '25 14:10 tharkum