mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
Add signal to request (#39290)
The signal taken from the requestinit is now passed into the request object with the relevant steps. I added all spec comments to this method, as I had trouble figuring out which steps I had to add. This required implementing the algorithm to create dependent signals, which is used in the `any()` method. So that's now implemented as well. All of that required the machinery to have dependent and source signals on an AbortSignal. It uses an IndexSet as the spec requires it to be an ordered set. Part of #34866 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
1898a740a8
commit
22fbb3458b
11 changed files with 278 additions and 266 deletions
|
@ -2,18 +2,21 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::cell::{Cell, RefCell};
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use indexmap::IndexSet;
|
||||
use js::jsapi::{ExceptionStackBehavior, Heap, JS_SetPendingException};
|
||||
use js::jsval::{JSVal, UndefinedValue};
|
||||
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
|
||||
use script_bindings::inheritance::Castable;
|
||||
use script_bindings::trace::CustomTraceable;
|
||||
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods;
|
||||
use crate::dom::bindings::error::{Error, ErrorToJsval};
|
||||
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::root::{Dom, DomRoot};
|
||||
use crate::dom::eventtarget::EventTarget;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::dom::readablestream::PipeTo;
|
||||
|
@ -48,6 +51,15 @@ pub(crate) struct AbortSignal {
|
|||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-abort-algorithms>
|
||||
abort_algorithms: RefCell<Vec<AbortAlgorithm>>,
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-dependent>
|
||||
dependent: Cell<bool>,
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-source-signals>
|
||||
source_signals: DomRefCell<IndexSet<Dom<AbortSignal>>>,
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-dependent-signals>
|
||||
dependent_signals: DomRefCell<IndexSet<Dom<AbortSignal>>>,
|
||||
}
|
||||
|
||||
impl AbortSignal {
|
||||
|
@ -56,6 +68,9 @@ impl AbortSignal {
|
|||
eventtarget: EventTarget::new_inherited(),
|
||||
abort_reason: Default::default(),
|
||||
abort_algorithms: Default::default(),
|
||||
dependent: Default::default(),
|
||||
source_signals: Default::default(),
|
||||
dependent_signals: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,6 +88,7 @@ impl AbortSignal {
|
|||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-signal-abort>
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))] // TODO(39333): Remove when all iterators are marked as safe
|
||||
pub(crate) fn signal_abort(
|
||||
&self,
|
||||
cx: SafeJSContext,
|
||||
|
@ -99,21 +115,25 @@ impl AbortSignal {
|
|||
}
|
||||
|
||||
// Step 3. Let dependentSignalsToAbort be a new list.
|
||||
// TODO
|
||||
let mut dependent_signals_to_abort = vec![];
|
||||
// Step 4. For each dependentSignal of signal’s dependent signals:
|
||||
// TODO
|
||||
// Step 4.1. If dependentSignal is not aborted:
|
||||
// TODO
|
||||
// Step 4.1.1. Set dependentSignal’s abort reason to signal’s abort reason.
|
||||
// TODO
|
||||
// Step 4.1.2. Append dependentSignal to dependentSignalsToAbort.
|
||||
// TODO
|
||||
for dependent_signal in self.dependent_signals.borrow().iter() {
|
||||
// Step 4.1. If dependentSignal is not aborted:
|
||||
if !dependent_signal.aborted() {
|
||||
// Step 4.1.1. Set dependentSignal’s abort reason to signal’s abort reason.
|
||||
dependent_signal.abort_reason.set(self.abort_reason.get());
|
||||
// Step 4.1.2. Append dependentSignal to dependentSignalsToAbort.
|
||||
dependent_signals_to_abort.push(dependent_signal.as_rooted());
|
||||
}
|
||||
}
|
||||
|
||||
// Step 5. Run the abort steps for signal.
|
||||
self.run_the_abort_steps(cx, &global, realm, can_gc);
|
||||
|
||||
// Step 6. For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
|
||||
// TODO
|
||||
for dependent_signal in dependent_signals_to_abort.iter() {
|
||||
dependent_signal.run_the_abort_steps(cx, &global, realm, can_gc);
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#abortsignal-add>
|
||||
|
@ -174,6 +194,61 @@ impl AbortSignal {
|
|||
// An AbortSignal object is aborted when its abort reason is not undefined.
|
||||
!self.abort_reason.get().is_undefined()
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#create-a-dependent-abort-signal>
|
||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))] // TODO(39333): Remove when all iterators are marked as safe
|
||||
pub(crate) fn create_dependent_abort_signal(
|
||||
signals: Vec<DomRoot<AbortSignal>>,
|
||||
global: &GlobalScope,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<AbortSignal> {
|
||||
// Step 1. Let resultSignal be a new object implementing signalInterface using realm.
|
||||
let result_signal = Self::new_with_proto(global, None, can_gc);
|
||||
// Step 2. For each signal of signals: if signal is aborted,
|
||||
// then set resultSignal’s abort reason to signal’s abort reason and return resultSignal.
|
||||
for signal in signals.iter() {
|
||||
if signal.aborted() {
|
||||
result_signal.abort_reason.set(signal.abort_reason.get());
|
||||
return result_signal;
|
||||
}
|
||||
}
|
||||
// Step 3. Set resultSignal’s dependent to true.
|
||||
result_signal.dependent.set(true);
|
||||
// Step 4. For each signal of signals:
|
||||
for signal in signals.iter() {
|
||||
// Step 4.1. If signal’s dependent is false:
|
||||
if !signal.dependent.get() {
|
||||
// Step 4.1.1. Append signal to resultSignal’s source signals.
|
||||
result_signal
|
||||
.source_signals
|
||||
.borrow_mut()
|
||||
.insert(Dom::from_ref(signal));
|
||||
// Step 4.1.2. Append resultSignal to signal’s dependent signals.
|
||||
signal
|
||||
.dependent_signals
|
||||
.borrow_mut()
|
||||
.insert(Dom::from_ref(&result_signal));
|
||||
} else {
|
||||
// Step 4.2. Otherwise, for each sourceSignal of signal’s source signals:
|
||||
for source_signal in signal.source_signals.borrow().iter() {
|
||||
// Step 4.2.1. Assert: sourceSignal is not aborted and not dependent.
|
||||
assert!(!source_signal.aborted() && !source_signal.dependent.get());
|
||||
// Step 4.2.2. Append sourceSignal to resultSignal’s source signals.
|
||||
result_signal
|
||||
.source_signals
|
||||
.borrow_mut()
|
||||
.insert(source_signal.clone());
|
||||
// Step 4.2.3. Append resultSignal to sourceSignal’s dependent signals.
|
||||
source_signal
|
||||
.dependent_signals
|
||||
.borrow_mut()
|
||||
.insert(Dom::from_ref(&result_signal));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Step 5. Return resultSignal.
|
||||
result_signal
|
||||
}
|
||||
}
|
||||
|
||||
impl AbortSignalMethods<crate::DomTypeHolder> for AbortSignal {
|
||||
|
@ -208,6 +283,17 @@ impl AbortSignalMethods<crate::DomTypeHolder> for AbortSignal {
|
|||
signal
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-abortsignal-any>
|
||||
fn Any(
|
||||
global: &GlobalScope,
|
||||
signals: Vec<DomRoot<AbortSignal>>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<AbortSignal> {
|
||||
// The static any(signals) method steps are to return the result
|
||||
// of creating a dependent abort signal from signals using AbortSignal and the current realm.
|
||||
Self::create_dependent_abort_signal(signals, global, can_gc)
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#dom-abortsignal-reason>
|
||||
fn Reason(&self, _cx: SafeJSContext, mut rval: MutableHandleValue) {
|
||||
// The reason getter steps are to return this’s abort reason.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue