[#26488] Moves the FetchCanceller to a separate droppable struct, in Event Source (#37261)

Testing: No tests added.
Fixes: partially fixes #26488

Signed-off-by: Domenico Rizzo <domenico.rizzo@gmail.com>
This commit is contained in:
Domenico Rizzo 2025-06-05 18:07:26 +02:00 committed by GitHub
parent 6cc3e2934c
commit 6d99c09499
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -61,6 +61,34 @@ enum ReadyState {
Closed = 2, Closed = 2,
} }
#[derive(JSTraceable, MallocSizeOf)]
struct DroppableEventSource {
canceller: DomRefCell<FetchCanceller>,
}
impl DroppableEventSource {
pub(crate) fn new(canceller: DomRefCell<FetchCanceller>) -> Self {
DroppableEventSource { canceller }
}
pub(crate) fn cancel(&self) {
self.canceller.borrow_mut().cancel();
}
pub(crate) fn set_canceller(&self, data: FetchCanceller) {
*self.canceller.borrow_mut() = data;
}
}
// https://html.spec.whatwg.org/multipage/#garbage-collection-2
impl Drop for DroppableEventSource {
fn drop(&mut self) {
// If an EventSource object is garbage collected while its connection is still open,
// the user agent must abort any instance of the fetch algorithm opened by this EventSource.
self.cancel();
}
}
#[dom_struct] #[dom_struct]
pub(crate) struct EventSource { pub(crate) struct EventSource {
eventtarget: EventTarget, eventtarget: EventTarget,
@ -74,7 +102,7 @@ pub(crate) struct EventSource {
ready_state: Cell<ReadyState>, ready_state: Cell<ReadyState>,
with_credentials: bool, with_credentials: bool,
canceller: DomRefCell<FetchCanceller>, droppable: DroppableEventSource,
} }
enum ParserState { enum ParserState {
@ -480,7 +508,7 @@ impl EventSource {
ready_state: Cell::new(ReadyState::Connecting), ready_state: Cell::new(ReadyState::Connecting),
with_credentials, with_credentials,
canceller: DomRefCell::new(Default::default()), droppable: DroppableEventSource::new(DomRefCell::new(Default::default())),
} }
} }
@ -501,7 +529,7 @@ impl EventSource {
// https://html.spec.whatwg.org/multipage/#sse-processing-model:fail-the-connection-3 // https://html.spec.whatwg.org/multipage/#sse-processing-model:fail-the-connection-3
pub(crate) fn cancel(&self) { pub(crate) fn cancel(&self) {
self.canceller.borrow_mut().cancel(); self.droppable.cancel();
self.fail_the_connection(); self.fail_the_connection();
} }
@ -529,15 +557,6 @@ impl EventSource {
} }
} }
// https://html.spec.whatwg.org/multipage/#garbage-collection-2
impl Drop for EventSource {
fn drop(&mut self) {
// If an EventSource object is garbage collected while its connection is still open,
// the user agent must abort any instance of the fetch algorithm opened by this EventSource.
self.canceller.borrow_mut().cancel();
}
}
impl EventSourceMethods<crate::DomTypeHolder> for EventSource { impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
// https://html.spec.whatwg.org/multipage/#dom-eventsource // https://html.spec.whatwg.org/multipage/#dom-eventsource
fn Constructor( fn Constructor(
@ -632,7 +651,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
listener.notify_fetch(message.unwrap()); listener.notify_fetch(message.unwrap());
}), }),
); );
*ev.canceller.borrow_mut() = FetchCanceller::new(request.id); ev.droppable.set_canceller(FetchCanceller::new(request.id));
global global
.core_resource_thread() .core_resource_thread()
.send(CoreResourceMsg::Fetch( .send(CoreResourceMsg::Fetch(
@ -672,7 +691,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
fn Close(&self) { fn Close(&self) {
let GenerationId(prev_id) = self.generation_id.get(); let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1)); self.generation_id.set(GenerationId(prev_id + 1));
self.canceller.borrow_mut().cancel(); self.droppable.cancel();
self.ready_state.set(ReadyState::Closed); self.ready_state.set(ReadyState::Closed);
} }
} }