Repository: servo/servo
File: components/script/dom/html/htmlmediaelement.rs (Rust)

Code before:
    }
}

impl HTMLMediaElementFetchListener {
    fn new(element: &HTMLMediaElement, request_id: RequestId, url: ServoUrl, offset: u64) -> Self {
        Self {
            element: Trusted::new(element),
            generation_id: element.generation_id.get(),
            request_id,
            next_progress_event: Instant::now() + Duration::from_millis(350),
            url,
            expected_content_length: None,
            fetched_content_length: 0,
            content_length_to_discard: offset,
        }
    }
}

/// The [`HTMLMediaElementEventHandler`] is a structure responsible for handling media events for
/// the [`HTMLMediaElement`] and exists to decouple ownership of the [`HTMLMediaElement`] from IPC
/// router callback.
#[derive(JSTraceable, MallocSizeOf)]
struct HTMLMediaElementEventHandler {
    element: WeakRef<HTMLMediaElement>,
}

#[expect(unsafe_code)]
unsafe impl Send for HTMLMediaElementEventHandler {}

impl HTMLMediaElementEventHandler {
    fn new(element: &HTMLMediaElement) -> Self {
        Self {
            element: WeakRef::new(element),
        }
    }

    fn handle_player_event(&self, player_id: usize, event: PlayerEvent, can_gc: CanGc) {
        let Some(element) = self.element.root() else {
            return;
        };

        // Abort event processing if the associated media player is outdated.
        if element.player_id().is_none_or(|id| id != player_id) {
            return;
        }

        match event {
            PlayerEvent::DurationChanged(duration) => element.playback_duration_changed(duration),
            PlayerEvent::EndOfStream => element.playback_end(),
            PlayerEvent::EnoughData => element.playback_enough_data(),
            PlayerEvent::Error(ref error) => element.playback_error(error, can_gc),

Review comment (suggestion):
I'm actually not sure if it is safe to send a DOM `WeakRef` across thread boundaries. I think this is a question for @jdm.

Code after:

impl HTMLMediaElementFetchListener {
    fn new(element: &HTMLMediaElement, request_id: RequestId, url: ServoUrl, offset: u64) -> Self {
        Self {
            element: Trusted::new(element),
            generation_id: element.generation_id.get(),
            request_id,
            next_progress_event: Instant::now() + Duration::from_millis(350),
            url,
            expected_content_length: None,
            fetched_content_length: 0,
            content_length_to_discard: offset,
        }
    }
}

/// The [`HTMLMediaElementEventHandler`] is a structure responsible for handling media events for
/// the [`HTMLMediaElement`] and exists to decouple ownership of the [`HTMLMediaElement`] from IPC
/// router callback.
#[derive(JSTraceable, MallocSizeOf)]
struct HTMLMediaElementEventHandler {
    element: WeakRef<HTMLMediaElement>,
}

#[expect(unsafe_code)]
unsafe impl Send for HTMLMediaElementEventHandler {}

impl HTMLMediaElementEventHandler {
    fn new(element: &HTMLMediaElement) -> Self {
        Self {
            element: WeakRef::new(element),
        }
    }

    fn handle_player_event(&self, player_id: usize, event: PlayerEvent, can_gc: CanGc) {
        let Some(element) = self.element.root() else {
            return;
        };

        // Abort event processing if the associated media player is outdated.
        if element.player_id().is_none_or(|id| id != player_id) {
            return;
        }

        match event {
            PlayerEvent::DurationChanged(duration) => element.playback_duration_changed(duration),
            PlayerEvent::EndOfStream => element.playback_end(),
            PlayerEvent::EnoughData => element.playback_enough_data(),
            PlayerEvent::Error(ref error) => element.playback_error(error, can_gc),
            PlayerEvent::MetadataUpdated(ref metadata) => {
                element.playback_metadata_updated(metadata, can_gc)