net: Use RequestId to cancel fetches instead of creating an IPC channel (#34883)

Instead of creating an IPC channel for every fetch, allow cancelling
fetches based on the `RequestId` of the original request. This requires
that `RequestId`s be UUIDs so that they are unique between processes
that might communicating with the resource process.

In addition, the resource process loop now keeps a `HashMap` or `Weak`
handles to cancellers and cleans them up.

This allows for creating mutiple `FetchCanceller`s in `script` for a
single fetch request, allowing integration of the media and video
elements to integrate with the `Document` canceller list -- meaning
these fetches also get cancelled when the `Document` unloads.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-01-11 12:49:22 +01:00 committed by GitHub
parent e2be55b873
commit 748954d610
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 179 additions and 226 deletions

View file

@ -3,7 +3,7 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::borrow::Cow;
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::{io, mem, str};
@ -15,7 +15,7 @@ use devtools_traits::DevtoolsControlMsg;
use headers::{AccessControlExposeHeaders, ContentType, HeaderMapExt};
use http::header::{self, HeaderMap, HeaderName};
use http::{Method, StatusCode};
use ipc_channel::ipc::{self, IpcReceiver};
use ipc_channel::ipc;
use log::warn;
use mime::{self, Mime};
use net_traits::filemanager_thread::{FileTokenCheck, RelativePos};
@ -59,37 +59,23 @@ pub struct FetchContext {
pub devtools_chan: Option<Arc<Mutex<Sender<DevtoolsControlMsg>>>>,
pub filemanager: Arc<Mutex<FileManager>>,
pub file_token: FileTokenCheck,
pub cancellation_listener: Arc<Mutex<CancellationListener>>,
pub cancellation_listener: Arc<CancellationListener>,
pub timing: ServoArc<Mutex<ResourceFetchTiming>>,
pub protocols: Arc<ProtocolRegistry>,
}
#[derive(Default)]
pub struct CancellationListener {
cancel_chan: Option<IpcReceiver<()>>,
cancelled: bool,
cancelled: AtomicBool,
}
impl CancellationListener {
pub fn new(cancel_chan: Option<IpcReceiver<()>>) -> Self {
Self {
cancel_chan,
cancelled: false,
}
pub(crate) fn cancelled(&self) -> bool {
self.cancelled.load(Ordering::Relaxed)
}
pub fn cancelled(&mut self) -> bool {
if let Some(ref cancel_chan) = self.cancel_chan {
if self.cancelled {
true
} else if cancel_chan.try_recv().is_ok() {
self.cancelled = true;
true
} else {
false
}
} else {
false
}
pub(crate) fn cancel(&self) {
self.cancelled.store(true, Ordering::Relaxed)
}
}
pub type DoneChannel = Option<(TokioSender<Data>, TokioReceiver<Data>)>;