Skip to content

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

@tharkum

Description

@tharkum

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>).

let this = trusted_node.clone();

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions