script: Have FetchResponseListener::process_response_eof consume the listener (#40556)

The goal of this change is to prevent having to copy so much data out of
listeners when a fetch completes, which will be particularly important
for off-the-main thread parsing of CSS (see #22478). This change has
pros and cons:

Pros:
- This makes the design of the `FetchResponseListener` a great deal
simpler.
They no longer individually store a dummy `ResourceFetchTiming` that is
   only replaced right before `process_response_eof`.
 - The creation of the `Arc<Mutex<FetchResponseListener>>` in the
   `NetworkListener` is abstracted away from clients and now they just
   pass the `FetchResponseListener` to the fetch methods in the global.

Cons:
 - Now each `FetchResponseListener` must explicitly call `submit_timing`
   instead of having the `NetworkListener` do it. This is arguably a bit
   easier to follow in the code.
 - Since the internal data of the `NetworkListener` is now an
   `Arc<Mutex<Option<FetchResponseListener>>>`, when the fetching code
   needs to share state with the `NetworkListener` it either needs to
   share an `Option` or some sort of internal state. In one case I've
   stored the `Option` and in another case, I've stored a new inner
   shared value.

Testing: This should not change observable behavior and is thus covered
by existing tests.
Fixes: #22550

---------

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson
2025-11-11 23:30:40 +01:00
committed by GitHub
parent 900243f00d
commit bfde51c0db
29 changed files with 301 additions and 560 deletions

View File

@@ -26,7 +26,6 @@ use media::{GLPlayerMsg, GLPlayerMsgForward, WindowGLContext};
use net_traits::request::{Destination, RequestId};
use net_traits::{
CoreResourceThread, FetchMetadata, FilteredMetadata, NetworkError, ResourceFetchTiming,
ResourceTimingType,
};
use pixels::RasterImage;
use script_bindings::codegen::GenericBindings::TimeRangesBinding::TimeRangesMethods;
@@ -3386,8 +3385,6 @@ struct HTMLMediaElementFetchListener {
request_id: RequestId,
/// Time of last progress notification.
next_progress_event: Instant,
/// Timing data for this resource.
resource_timing: ResourceFetchTiming,
/// Url for the resource.
url: ServoUrl,
/// Expected content length of the media asset being fetched or played.
@@ -3540,11 +3537,7 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
}
}
fn process_response_eof(
&mut self,
_: RequestId,
status: Result<ResourceFetchTiming, NetworkError>,
) {
fn process_response_eof(self, _: RequestId, status: Result<ResourceFetchTiming, NetworkError>) {
let element = self.element.root();
// <https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list>
@@ -3602,18 +3595,10 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
// unsupported format, or can otherwise not be rendered at all"
element.media_data_processing_failure_steps();
}
}
fn resource_timing_mut(&mut self) -> &mut ResourceFetchTiming {
&mut self.resource_timing
}
fn resource_timing(&self) -> &ResourceFetchTiming {
&self.resource_timing
}
fn submit_resource_timing(&mut self) {
network_listener::submit_timing(self, CanGc::note())
if let Ok(response) = status {
network_listener::submit_timing(&self, &response, CanGc::note());
}
}
fn process_csp_violations(&mut self, _request_id: RequestId, violations: Vec<Violation>) {
@@ -3673,7 +3658,6 @@ impl HTMLMediaElementFetchListener {
generation_id: element.generation_id.get(),
request_id,
next_progress_event: Instant::now() + Duration::from_millis(350),
resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource),
url,
expected_content_length: None,
fetched_content_length: 0,