script: Stop using time in DOM timers (#33262)

This switches to using `std::time` types for DOM timer operations, which
allows removing our custom time units in favor of `Duration`.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2024-08-30 17:20:44 +02:00 committed by GitHub
parent 8a0c7487e7
commit a4ceb82ef5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 78 additions and 106 deletions

View file

@ -47,8 +47,7 @@ use profile_traits::time::{TimerMetadata, TimerMetadataFrameType, TimerMetadataR
use script_layout_interface::{PendingRestyle, ReflowGoal, TrustedNodeAddress};
use script_traits::{
AnimationState, AnimationTickType, CompositorEvent, DocumentActivity, MouseButton,
MouseEventType, MsDuration, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress,
WheelDelta,
MouseEventType, ScriptMsg, TouchEventType, TouchId, UntrustedNodeAddress, WheelDelta,
};
use servo_arc::Arc;
use servo_atoms::Atom;
@ -1993,7 +1992,7 @@ impl Document {
};
self.global().schedule_callback(
OneshotTimerCallback::FakeRequestAnimationFrame(callback),
MsDuration::new(FAKE_REQUEST_ANIMATION_FRAME_DELAY),
Duration::from_millis(FAKE_REQUEST_ANIMATION_FRAME_DELAY),
);
} else if !self.running_animation_callbacks.get() {
// No need to send a `ChangeRunningAnimationsState` if we're running animation callbacks:
@ -2443,7 +2442,7 @@ impl Document {
window: window_from_node(&*document),
url: url.clone(),
}),
MsDuration::new(time.saturating_mul(1000)),
Duration::from_secs(*time),
);
}
// Note: this will, among others, result in the "iframe-load-event-steps" being run.

View file

@ -6,9 +6,9 @@ use std::cell::Cell;
use std::mem;
use std::str::{Chars, FromStr};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use dom_struct::dom_struct;
use euclid::Length;
use headers::ContentType;
use http::header::{self, HeaderName, HeaderValue};
use ipc_channel::ipc;
@ -48,7 +48,7 @@ use crate::script_runtime::CanGc;
use crate::task_source::{TaskSource, TaskSourceName};
use crate::timers::OneshotTimerCallback;
const DEFAULT_RECONNECTION_TIME: u64 = 5000;
const DEFAULT_RECONNECTION_TIME: Duration = Duration::from_millis(5000);
#[derive(Clone, Copy, Debug, JSTraceable, MallocSizeOf, PartialEq)]
struct GenerationId(u32);
@ -69,7 +69,7 @@ pub struct EventSource {
#[no_trace]
request: DomRefCell<Option<RequestBuilder>>,
last_event_id: DomRefCell<DOMString>,
reconnection_time: Cell<u64>,
reconnection_time: Cell<Duration>,
generation_id: Cell<GenerationId>,
ready_state: Cell<ReadyState>,
@ -162,7 +162,7 @@ impl EventSourceContext {
event_source.upcast::<EventTarget>().fire_event(atom!("error"));
// Step 2.
let duration = Length::new(event_source.reconnection_time.get());
let duration = event_source.reconnection_time.get();
// Step 3.
// TODO: Optionally wait some more.
@ -192,7 +192,10 @@ impl EventSourceContext {
"id" => mem::swap(&mut self.last_event_id, &mut self.value),
"retry" => {
if let Ok(time) = u64::from_str(&self.value) {
self.event_source.root().reconnection_time.set(time);
self.event_source
.root()
.reconnection_time
.set(Duration::from_millis(time));
}
},
_ => (),

View file

@ -11,7 +11,7 @@ use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::thread::JoinHandle;
use std::time::{Instant, SystemTime, UNIX_EPOCH};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
use std::{mem, ptr};
use base::id::{
@ -53,7 +53,7 @@ use script_traits::serializable::{BlobData, BlobImpl, FileBlob};
use script_traits::transferable::MessagePortImpl;
use script_traits::{
BroadcastMsg, GamepadEvent, GamepadSupportedHapticEffects, GamepadUpdateType, MessagePortMsg,
MsDuration, PortMessageTask, ScriptMsg, ScriptToConstellationChan, TimerEvent, TimerEventId,
PortMessageTask, ScriptMsg, ScriptToConstellationChan, TimerEvent, TimerEventId,
TimerSchedulerMsg, TimerSource,
};
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
@ -2741,7 +2741,7 @@ impl GlobalScope {
pub fn schedule_callback(
&self,
callback: OneshotTimerCallback,
duration: MsDuration,
duration: Duration,
) -> OneshotTimerHandle {
self.setup_timers();
self.timers
@ -2757,7 +2757,7 @@ impl GlobalScope {
&self,
callback: TimerCallback,
arguments: Vec<HandleValue>,
timeout: i32,
timeout: Duration,
is_interval: IsInterval,
) -> i32 {
self.setup_timers();

View file

@ -4,12 +4,13 @@
use std::str::FromStr;
use std::sync::LazyLock;
use std::time::Duration;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use js::rust::HandleObject;
use regex::bytes::Regex;
use script_traits::{HistoryEntryReplacement, MsDuration};
use script_traits::HistoryEntryReplacement;
use servo_url::ServoUrl;
use style::str::HTML_SPACE_CHARACTERS;
@ -207,7 +208,7 @@ impl HTMLMetaElement {
window: window.clone(),
url: url_record,
}),
MsDuration::new(time.saturating_mul(1000)),
Duration::from_secs(time),
);
document.set_declarative_refresh(DeclarativeRefresh::CreatedAfterLoad);
} else {

View file

@ -7,6 +7,7 @@
use std::borrow::ToOwned;
use std::ptr::{self, NonNull};
use std::rc::Rc;
use std::time::Duration;
use dom_struct::dom_struct;
use js::jsapi::{Heap, JSObject, JS_NewPlainObject};
@ -14,7 +15,6 @@ use js::jsval::{JSVal, NullValue};
use js::rust::{CustomAutoRooterGuard, HandleObject, HandleValue};
use js::typedarray::{self, Uint8ClampedArray};
use script_traits::serializable::BlobImpl;
use script_traits::MsDuration;
use servo_config::prefs;
use crate::dom::bindings::buffer_source::create_buffer_source;
@ -999,7 +999,7 @@ impl TestBindingMethods for TestBinding {
};
let _ = self.global().schedule_callback(
OneshotTimerCallback::TestBindingCallback(cb),
MsDuration::new(delay),
Duration::from_millis(delay),
);
}

View file

@ -12,6 +12,7 @@ use std::ptr::NonNull;
use std::rc::Rc;
use std::sync::atomic::Ordering;
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{cmp, env, mem};
use app_units::Au;
@ -882,7 +883,7 @@ impl WindowMethods for Window {
self.upcast::<GlobalScope>().set_timeout_or_interval(
callback,
args,
timeout,
Duration::from_millis(timeout.max(0) as u64),
IsInterval::NonInterval,
)
}
@ -908,7 +909,7 @@ impl WindowMethods for Window {
self.upcast::<GlobalScope>().set_timeout_or_interval(
callback,
args,
timeout,
Duration::from_millis(timeout.max(0) as u64),
IsInterval::Interval,
)
}

View file

@ -6,6 +6,7 @@ use std::default::Default;
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
use std::time::Duration;
use base::id::{PipelineId, PipelineNamespace};
use crossbeam_channel::Receiver;
@ -345,7 +346,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
self.upcast::<GlobalScope>().set_timeout_or_interval(
callback,
args,
timeout,
Duration::from_millis(timeout.max(0) as u64),
IsInterval::NonInterval,
)
}
@ -371,7 +372,7 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
self.upcast::<GlobalScope>().set_timeout_or_interval(
callback,
args,
timeout,
Duration::from_millis(timeout.max(0) as u64),
IsInterval::Interval,
)
}

View file

@ -7,11 +7,11 @@ use std::cell::Cell;
use std::default::Default;
use std::str::{self, FromStr};
use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant};
use std::{cmp, slice};
use dom_struct::dom_struct;
use encoding_rs::{Encoding, UTF_8};
use euclid::Length;
use headers::{ContentLength, ContentType, HeaderMapExt};
use html5ever::serialize;
use html5ever::serialize::SerializeOpts;
@ -125,7 +125,7 @@ impl XHRProgress {
pub struct XMLHttpRequest {
eventtarget: XMLHttpRequestEventTarget,
ready_state: Cell<XMLHttpRequestState>,
timeout: Cell<u32>,
timeout: Cell<Duration>,
with_credentials: Cell<bool>,
upload: Dom<XMLHttpRequestUpload>,
response_url: DomRefCell<String>,
@ -162,7 +162,7 @@ pub struct XMLHttpRequest {
send_flag: Cell<bool>,
timeout_cancel: DomRefCell<Option<OneshotTimerHandle>>,
fetch_time: Cell<i64>,
fetch_time: Cell<Instant>,
generation_id: Cell<GenerationId>,
response_status: Cell<Result<(), ()>>,
#[no_trace]
@ -185,7 +185,7 @@ impl XMLHttpRequest {
XMLHttpRequest {
eventtarget: XMLHttpRequestEventTarget::new_inherited(),
ready_state: Cell::new(XMLHttpRequestState::Unsent),
timeout: Cell::new(0u32),
timeout: Cell::new(Duration::ZERO),
with_credentials: Cell::new(false),
upload: Dom::from_ref(&*XMLHttpRequestUpload::new(global)),
response_url: DomRefCell::new(String::new()),
@ -210,7 +210,7 @@ impl XMLHttpRequest {
send_flag: Cell::new(false),
timeout_cancel: DomRefCell::new(None),
fetch_time: Cell::new(0),
fetch_time: Cell::new(Instant::now()),
generation_id: Cell::new(GenerationId(0)),
response_status: Cell::new(Ok(())),
referrer: global.get_referrer(),
@ -420,7 +420,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// Step 10
if !asynch {
// FIXME: This should only happen if the global environment is a document environment
if self.timeout.get() != 0 ||
if !self.timeout.get().is_zero() ||
self.response_type.get() != XMLHttpRequestResponseType::_empty
{
return Err(Error::InvalidAccess);
@ -514,7 +514,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
/// <https://xhr.spec.whatwg.org/#the-timeout-attribute>
fn Timeout(&self) -> u32 {
self.timeout.get()
self.timeout.get().as_millis() as u32
}
/// <https://xhr.spec.whatwg.org/#the-timeout-attribute>
@ -523,20 +523,22 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
if self.sync_in_window() {
return Err(Error::InvalidAccess);
}
// Step 2
let timeout = Duration::from_millis(timeout as u64);
self.timeout.set(timeout);
if self.send_flag.get() {
if timeout == 0 {
if timeout.is_zero() {
self.cancel_timeout();
return Ok(());
}
let progress = time::now().to_timespec().sec - self.fetch_time.get();
if timeout > (progress * 1000) as u32 {
self.set_timeout(timeout - (progress * 1000) as u32);
let progress = Instant::now() - self.fetch_time.get();
if timeout > progress {
self.set_timeout(timeout - progress);
} else {
// Immediately execute the timeout steps
self.set_timeout(0);
self.set_timeout(Duration::ZERO);
}
}
Ok(())
@ -788,7 +790,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
}
}
self.fetch_time.set(time::now().to_timespec().sec);
self.fetch_time.set(Instant::now());
let rv = self.fetch(request, &self.global());
// Step 10
@ -797,7 +799,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
}
let timeout = self.timeout.get();
if timeout > 0 {
if timeout > Duration::ZERO {
self.set_timeout(timeout);
}
Ok(())
@ -1298,14 +1300,13 @@ impl XMLHttpRequest {
self.dispatch_progress_event(false, type_, len, total);
}
fn set_timeout(&self, duration_ms: u32) {
fn set_timeout(&self, duration: Duration) {
// Sets up the object to timeout in a given number of milliseconds
// This will cancel all previous timeouts
let callback = OneshotTimerCallback::XhrTimeout(XHRTimeoutCallback {
xhr: Trusted::new(self),
generation_id: self.generation_id.get(),
});
let duration = Length::new(duration_ms as u64);
*self.timeout_cancel.borrow_mut() =
Some(self.global().schedule_callback(callback, duration));
}