Repository: servo/servo
File: components/script/document_loader.rs (Rust)

Code before:
        if let Some(blocker) = blocker.borrow().as_ref() {
            blocker.doc.finish_load(load, can_gc);
        }

        *blocker.borrow_mut() = None;
    }
}

impl Drop for LoadBlocker {
    fn drop(&mut self) {
        if let Some(load) = self.load.take() {
            self.doc.finish_load(load, CanGc::note());
        }
    }
}

#[derive(JSTraceable, MallocSizeOf)]
pub(crate) struct DocumentLoader {
    #[no_trace]
    resource_threads: ResourceThreads,
    blocking_loads: Vec<LoadType>,
    events_inhibited: bool,
    cancellers: Vec<FetchCanceller>,
    /// <https://fetch.spec.whatwg.org/#fetch-group-deferred-fetch-records>
    #[no_trace]
    deferred_fetches: AtomicRefCell<Vec<DeferredFetchRecord>>,
}

impl DocumentLoader {
    pub(crate) fn new(existing: &DocumentLoader) -> DocumentLoader {
        DocumentLoader::new_with_threads(existing.resource_threads.clone(), None)
    }

    pub(crate) fn new_with_threads(
        resource_threads: ResourceThreads,
        initial_load: Option<ServoUrl>,
    ) -> DocumentLoader {
        debug!("Initial blocking load {:?}.", initial_load);
        let initial_loads = initial_load.into_iter().map(LoadType::PageSource).collect();

        DocumentLoader {
            resource_threads,
            blocking_loads: initial_loads,
            events_inhibited: false,
            cancellers: Vec::new(),
            deferred_fetches: Default::default(),
        }
    }

    /// <https://fetch.spec.whatwg.org/#concept-fetch-group-terminate>
    pub(crate) fn cancel_all_loads(&mut self) -> bool {

Review comment (suggestion):
Going by https://github.com/servo/servo/issues/41286#issuecomment-3675011906, I think the idea is:
* move deferred_fetches to GlobalScope, and wrap it in a RefCell.
* move logic related to deferred_fetches from DocumentLoader into GlobalScope

Maybe that's enough? The GlobalScope already seems to be the place that callers use to interact with the document loader's deferred fetches right now.

Code after:
            blocker.doc.finish_load(load, can_gc);
        }

        *blocker.borrow_mut() = None;
    }
}

impl Drop for LoadBlocker {
    fn drop(&mut self) {
        if let Some(load) = self.load.take() {
            self.doc.finish_load(load, CanGc::note());
        }
    }
}

#[derive(JSTraceable, MallocSizeOf)]
pub(crate) struct DocumentLoader {
    #[no_trace]
    resource_threads: ResourceThreads,
    blocking_loads: Vec<LoadType>,
    events_inhibited: bool,
    cancellers: Vec<FetchCanceller>,
}

impl DocumentLoader {
    pub(crate) fn new(existing: &DocumentLoader) -> DocumentLoader {
        DocumentLoader::new_with_threads(existing.resource_threads.clone(), None)
    }

    pub(crate) fn new_with_threads(
        resource_threads: ResourceThreads,
        initial_load: Option<ServoUrl>,
    ) -> DocumentLoader {
        debug!("Initial blocking load {:?}.", initial_load);
        let initial_loads = initial_load.into_iter().map(LoadType::PageSource).collect();

        DocumentLoader {
            resource_threads,
            blocking_loads: initial_loads,
            events_inhibited: false,
            cancellers: Vec::new(),
        }
    }

    /// <https://fetch.spec.whatwg.org/#concept-fetch-group-terminate>
    pub(crate) fn cancel_all_loads(&mut self) -> Vec<FetchCanceller> {
        self.cancellers.drain(..).collect()
    }

    /// Add a load to the list of blocking loads.
    fn add_blocking_load(&mut self, load: LoadType) {