mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
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:
parent
e2be55b873
commit
748954d610
23 changed files with 179 additions and 226 deletions
|
@ -10,7 +10,7 @@ use std::fs::File;
|
|||
use std::io::prelude::*;
|
||||
use std::io::{self, BufReader};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::{Arc, Mutex, RwLock, Weak};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
|
@ -24,7 +24,7 @@ use log::{debug, warn};
|
|||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||
use net_traits::blob_url_store::parse_blob_url;
|
||||
use net_traits::filemanager_thread::FileTokenCheck;
|
||||
use net_traits::request::{Destination, RequestBuilder};
|
||||
use net_traits::request::{Destination, RequestBuilder, RequestId};
|
||||
use net_traits::response::{Response, ResponseInit};
|
||||
use net_traits::storage_thread::StorageThreadMsg;
|
||||
use net_traits::{
|
||||
|
@ -142,6 +142,7 @@ pub fn new_core_resource_thread(
|
|||
config_dir,
|
||||
ca_certificates,
|
||||
ignore_certificate_errors,
|
||||
cancellation_listeners: Default::default(),
|
||||
};
|
||||
|
||||
mem_profiler_chan.run_with_memory_reporting(
|
||||
|
@ -168,6 +169,7 @@ struct ResourceChannelManager {
|
|||
config_dir: Option<PathBuf>,
|
||||
ca_certificates: CACertificates,
|
||||
ignore_certificate_errors: bool,
|
||||
cancellation_listeners: HashMap<RequestId, Weak<CancellationListener>>,
|
||||
}
|
||||
|
||||
fn create_http_states(
|
||||
|
@ -300,6 +302,30 @@ impl ResourceChannelManager {
|
|||
msg.send(vec![public_report, private_report]);
|
||||
}
|
||||
|
||||
fn cancellation_listener(&self, request_id: RequestId) -> Option<Arc<CancellationListener>> {
|
||||
self.cancellation_listeners
|
||||
.get(&request_id)
|
||||
.and_then(Weak::upgrade)
|
||||
}
|
||||
|
||||
fn get_or_create_cancellation_listener(
|
||||
&mut self,
|
||||
request_id: RequestId,
|
||||
) -> Arc<CancellationListener> {
|
||||
if let Some(listener) = self.cancellation_listener(request_id) {
|
||||
return listener;
|
||||
}
|
||||
|
||||
// Clear away any cancellation listeners that are no longer valid.
|
||||
self.cancellation_listeners
|
||||
.retain(|_, listener| listener.strong_count() > 0);
|
||||
|
||||
let cancellation_listener = Arc::new(Default::default());
|
||||
self.cancellation_listeners
|
||||
.insert(request_id, Arc::downgrade(&cancellation_listener));
|
||||
cancellation_listener
|
||||
}
|
||||
|
||||
/// Returns false if the thread should exit.
|
||||
fn process_msg(
|
||||
&mut self,
|
||||
|
@ -308,33 +334,45 @@ impl ResourceChannelManager {
|
|||
protocols: Arc<ProtocolRegistry>,
|
||||
) -> bool {
|
||||
match msg {
|
||||
CoreResourceMsg::Fetch(req_init, channels) => match channels {
|
||||
FetchChannels::ResponseMsg(sender, cancel_chan) => self.resource_manager.fetch(
|
||||
req_init,
|
||||
None,
|
||||
sender,
|
||||
http_state,
|
||||
cancel_chan,
|
||||
protocols,
|
||||
),
|
||||
CoreResourceMsg::Fetch(request_builder, channels) => match channels {
|
||||
FetchChannels::ResponseMsg(sender) => {
|
||||
let cancellation_listener =
|
||||
self.get_or_create_cancellation_listener(request_builder.id);
|
||||
self.resource_manager.fetch(
|
||||
request_builder,
|
||||
None,
|
||||
sender,
|
||||
http_state,
|
||||
cancellation_listener,
|
||||
protocols,
|
||||
);
|
||||
},
|
||||
FetchChannels::WebSocket {
|
||||
event_sender,
|
||||
action_receiver,
|
||||
} => self.resource_manager.websocket_connect(
|
||||
req_init,
|
||||
request_builder,
|
||||
event_sender,
|
||||
action_receiver,
|
||||
http_state,
|
||||
),
|
||||
FetchChannels::Prefetch => self.resource_manager.fetch(
|
||||
req_init,
|
||||
request_builder,
|
||||
None,
|
||||
DiscardFetch,
|
||||
http_state,
|
||||
None,
|
||||
Arc::new(Default::default()),
|
||||
protocols,
|
||||
),
|
||||
},
|
||||
CoreResourceMsg::Cancel(request_ids) => {
|
||||
for cancellation_listener in request_ids
|
||||
.into_iter()
|
||||
.filter_map(|request_id| self.cancellation_listener(request_id))
|
||||
{
|
||||
cancellation_listener.cancel();
|
||||
}
|
||||
},
|
||||
CoreResourceMsg::DeleteCookies(request) => {
|
||||
http_state
|
||||
.cookie_jar
|
||||
|
@ -343,13 +381,15 @@ impl ResourceChannelManager {
|
|||
.clear_storage(&request);
|
||||
return true;
|
||||
},
|
||||
CoreResourceMsg::FetchRedirect(req_init, res_init, sender, cancel_chan) => {
|
||||
CoreResourceMsg::FetchRedirect(request_builder, res_init, sender) => {
|
||||
let cancellation_listener =
|
||||
self.get_or_create_cancellation_listener(request_builder.id);
|
||||
self.resource_manager.fetch(
|
||||
req_init,
|
||||
request_builder,
|
||||
Some(res_init),
|
||||
sender,
|
||||
http_state,
|
||||
cancel_chan,
|
||||
cancellation_listener,
|
||||
protocols,
|
||||
)
|
||||
},
|
||||
|
@ -698,7 +738,7 @@ impl CoreResourceManager {
|
|||
res_init_: Option<ResponseInit>,
|
||||
mut sender: Target,
|
||||
http_state: &Arc<HttpState>,
|
||||
cancel_chan: Option<IpcReceiver<()>>,
|
||||
cancellation_listener: Arc<CancellationListener>,
|
||||
protocols: Arc<ProtocolRegistry>,
|
||||
) {
|
||||
let http_state = http_state.clone();
|
||||
|
@ -746,7 +786,7 @@ impl CoreResourceManager {
|
|||
devtools_chan: dc.map(|dc| Arc::new(Mutex::new(dc))),
|
||||
filemanager: Arc::new(Mutex::new(filemanager)),
|
||||
file_token,
|
||||
cancellation_listener: Arc::new(Mutex::new(CancellationListener::new(cancel_chan))),
|
||||
cancellation_listener,
|
||||
timing: ServoArc::new(Mutex::new(ResourceFetchTiming::new(request.timing_type()))),
|
||||
protocols,
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue