mirror of
https://github.com/servo/servo.git
synced 2025-08-06 14:10:11 +01:00
Move timers to GlobalScope
This commit is contained in:
parent
5d8979237b
commit
991801488c
8 changed files with 144 additions and 145 deletions
|
@ -20,9 +20,7 @@ use js::jsapi::{CurrentGlobalOrNull, GetGlobalForObjectCrossCompartment};
|
||||||
use js::jsapi::{JSContext, JSObject, JS_GetClass};
|
use js::jsapi::{JSContext, JSObject, JS_GetClass};
|
||||||
use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan, ScriptPort};
|
use script_runtime::{CommonScriptMsg, EnqueuedPromiseCallback, ScriptChan, ScriptPort};
|
||||||
use script_thread::{RunnableWrapper, ScriptThread};
|
use script_thread::{RunnableWrapper, ScriptThread};
|
||||||
use script_traits::MsDuration;
|
|
||||||
use task_source::file_reading::FileReadingTaskSource;
|
use task_source::file_reading::FileReadingTaskSource;
|
||||||
use timers::{OneshotTimerCallback, OneshotTimerHandle};
|
|
||||||
|
|
||||||
/// A freely-copyable reference to a rooted global object.
|
/// A freely-copyable reference to a rooted global object.
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
|
@ -87,26 +85,6 @@ impl<'a> GlobalRef<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Schedule the given `callback` to be invoked after at least `duration` milliseconds have
|
|
||||||
/// passed.
|
|
||||||
pub fn schedule_callback(&self,
|
|
||||||
callback: OneshotTimerCallback,
|
|
||||||
duration: MsDuration)
|
|
||||||
-> OneshotTimerHandle {
|
|
||||||
match *self {
|
|
||||||
GlobalRef::Window(window) => window.schedule_callback(callback, duration),
|
|
||||||
GlobalRef::Worker(worker) => worker.schedule_callback(callback, duration),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Unschedule a previously-scheduled callback.
|
|
||||||
pub fn unschedule_callback(&self, handle: OneshotTimerHandle) {
|
|
||||||
match *self {
|
|
||||||
GlobalRef::Window(window) => window.unschedule_callback(handle),
|
|
||||||
GlobalRef::Worker(worker) => worker.unschedule_callback(handle),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a wrapper for runnables to ensure they are cancelled if the global
|
/// Returns a wrapper for runnables to ensure they are cancelled if the global
|
||||||
/// is being destroyed.
|
/// is being destroyed.
|
||||||
pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
|
pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
|
||||||
|
|
|
@ -28,13 +28,16 @@ use net_traits::{CoreResourceThread, ResourceThreads, IpcSend};
|
||||||
use profile_traits::{mem, time};
|
use profile_traits::{mem, time};
|
||||||
use script_runtime::{ScriptChan, maybe_take_panic_result};
|
use script_runtime::{ScriptChan, maybe_take_panic_result};
|
||||||
use script_thread::MainThreadScriptChan;
|
use script_thread::MainThreadScriptChan;
|
||||||
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest};
|
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEvent};
|
||||||
|
use script_traits::{TimerEventId, TimerEventRequest, TimerSource};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::hash_map::Entry;
|
use std::collections::hash_map::Entry;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
use time::{Timespec, get_time};
|
use time::{Timespec, get_time};
|
||||||
|
use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle};
|
||||||
|
use timers::{OneshotTimers, TimerCallback};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
#[dom_struct]
|
#[dom_struct]
|
||||||
|
@ -78,6 +81,8 @@ pub struct GlobalScope {
|
||||||
/// Associated resource threads for use by DOM objects like XMLHttpRequest,
|
/// Associated resource threads for use by DOM objects like XMLHttpRequest,
|
||||||
/// including resource_thread, filemanager_thread and storage_thread
|
/// including resource_thread, filemanager_thread and storage_thread
|
||||||
resource_threads: ResourceThreads,
|
resource_threads: ResourceThreads,
|
||||||
|
|
||||||
|
timers: OneshotTimers,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GlobalScope {
|
impl GlobalScope {
|
||||||
|
@ -88,7 +93,8 @@ impl GlobalScope {
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
constellation_chan: IpcSender<ConstellationMsg>,
|
constellation_chan: IpcSender<ConstellationMsg>,
|
||||||
scheduler_chan: IpcSender<TimerEventRequest>,
|
scheduler_chan: IpcSender<TimerEventRequest>,
|
||||||
resource_threads: ResourceThreads)
|
resource_threads: ResourceThreads,
|
||||||
|
timer_event_chan: IpcSender<TimerEvent>)
|
||||||
-> Self {
|
-> Self {
|
||||||
GlobalScope {
|
GlobalScope {
|
||||||
eventtarget: EventTarget::new_inherited(),
|
eventtarget: EventTarget::new_inherited(),
|
||||||
|
@ -101,9 +107,10 @@ impl GlobalScope {
|
||||||
mem_profiler_chan: mem_profiler_chan,
|
mem_profiler_chan: mem_profiler_chan,
|
||||||
time_profiler_chan: time_profiler_chan,
|
time_profiler_chan: time_profiler_chan,
|
||||||
constellation_chan: constellation_chan,
|
constellation_chan: constellation_chan,
|
||||||
scheduler_chan: scheduler_chan,
|
scheduler_chan: scheduler_chan.clone(),
|
||||||
in_error_reporting_mode: Default::default(),
|
in_error_reporting_mode: Default::default(),
|
||||||
resource_threads: resource_threads,
|
resource_threads: resource_threads,
|
||||||
|
timers: OneshotTimers::new(timer_event_chan, scheduler_chan),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +341,61 @@ impl GlobalScope {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn schedule_callback(
|
||||||
|
&self, callback: OneshotTimerCallback, duration: MsDuration)
|
||||||
|
-> OneshotTimerHandle {
|
||||||
|
self.timers.schedule_callback(callback, duration, self.timer_source())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unschedule_callback(&self, handle: OneshotTimerHandle) {
|
||||||
|
self.timers.unschedule_callback(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_timeout_or_interval(
|
||||||
|
&self,
|
||||||
|
callback: TimerCallback,
|
||||||
|
arguments: Vec<HandleValue>,
|
||||||
|
timeout: i32,
|
||||||
|
is_interval: IsInterval)
|
||||||
|
-> i32 {
|
||||||
|
self.timers.set_timeout_or_interval(
|
||||||
|
self, callback, arguments, timeout, is_interval, self.timer_source())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_timeout_or_interval(&self, handle: i32) {
|
||||||
|
self.timers.clear_timeout_or_interval(self, handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fire_timer(&self, handle: TimerEventId) {
|
||||||
|
self.timers.fire_timer(handle, self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resume(&self) {
|
||||||
|
self.timers.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn suspend(&self) {
|
||||||
|
self.timers.suspend()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn slow_down_timers(&self) {
|
||||||
|
self.timers.slow_down()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn speed_up_timers(&self) {
|
||||||
|
self.timers.speed_up()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timer_source(&self) -> TimerSource {
|
||||||
|
if self.is::<Window>() {
|
||||||
|
return TimerSource::FromWindow(self.pipeline_id());
|
||||||
|
}
|
||||||
|
if self.is::<WorkerGlobalScope>() {
|
||||||
|
return TimerSource::FromWorker;
|
||||||
|
}
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timestamp_in_ms(time: Timespec) -> u64 {
|
fn timestamp_in_ms(time: Timespec) -> u64 {
|
||||||
|
|
|
@ -683,8 +683,10 @@ impl TestBindingMethods for TestBinding {
|
||||||
promise: TrustedPromise::new(promise),
|
promise: TrustedPromise::new(promise),
|
||||||
value: value,
|
value: value,
|
||||||
};
|
};
|
||||||
let _ = self.global().r().schedule_callback(OneshotTimerCallback::TestBindingCallback(cb),
|
let _ = self.global_scope()
|
||||||
MsDuration::new(delay));
|
.schedule_callback(
|
||||||
|
OneshotTimerCallback::TestBindingCallback(cb),
|
||||||
|
MsDuration::new(delay));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unrooted_must_root)]
|
#[allow(unrooted_must_root)]
|
||||||
|
|
|
@ -71,8 +71,8 @@ use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventC
|
||||||
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper};
|
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, RunnableWrapper};
|
||||||
use script_thread::SendableMainThreadScriptChan;
|
use script_thread::SendableMainThreadScriptChan;
|
||||||
use script_traits::{ConstellationControlMsg, MozBrowserEvent, UntrustedNodeAddress};
|
use script_traits::{ConstellationControlMsg, MozBrowserEvent, UntrustedNodeAddress};
|
||||||
use script_traits::{DocumentState, MsDuration, TimerEvent, TimerEventId};
|
use script_traits::{DocumentState, TimerEvent, TimerEventId};
|
||||||
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, TimerSource, WindowSizeData};
|
use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData};
|
||||||
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
|
||||||
use std::ascii::AsciiExt;
|
use std::ascii::AsciiExt;
|
||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
@ -97,7 +97,7 @@ use task_source::history_traversal::HistoryTraversalTaskSource;
|
||||||
use task_source::networking::NetworkingTaskSource;
|
use task_source::networking::NetworkingTaskSource;
|
||||||
use task_source::user_interaction::UserInteractionTaskSource;
|
use task_source::user_interaction::UserInteractionTaskSource;
|
||||||
use time;
|
use time;
|
||||||
use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers, TimerCallback};
|
use timers::{IsInterval, TimerCallback};
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
#[cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))]
|
||||||
use tinyfiledialogs::{self, MessageBoxIcon};
|
use tinyfiledialogs::{self, MessageBoxIcon};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -168,7 +168,6 @@ pub struct Window {
|
||||||
session_storage: MutNullableHeap<JS<Storage>>,
|
session_storage: MutNullableHeap<JS<Storage>>,
|
||||||
local_storage: MutNullableHeap<JS<Storage>>,
|
local_storage: MutNullableHeap<JS<Storage>>,
|
||||||
status: DOMRefCell<DOMString>,
|
status: DOMRefCell<DOMString>,
|
||||||
timers: OneshotTimers,
|
|
||||||
|
|
||||||
/// For sending timeline markers. Will be ignored if
|
/// For sending timeline markers. Will be ignored if
|
||||||
/// no devtools server
|
/// no devtools server
|
||||||
|
@ -475,47 +474,43 @@ impl WindowMethods for Window {
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
||||||
fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Window(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::FunctionTimerCallback(callback),
|
TimerCallback::FunctionTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::NonInterval,
|
IsInterval::NonInterval)
|
||||||
TimerSource::FromWindow(self.upcast::<GlobalScope>().pipeline_id()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
||||||
fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Window(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::StringTimerCallback(callback),
|
TimerCallback::StringTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::NonInterval,
|
IsInterval::NonInterval)
|
||||||
TimerSource::FromWindow(self.upcast::<GlobalScope>().pipeline_id()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-cleartimeout
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-cleartimeout
|
||||||
fn ClearTimeout(&self, handle: i32) {
|
fn ClearTimeout(&self, handle: i32) {
|
||||||
self.timers.clear_timeout_or_interval(GlobalRef::Window(self), handle);
|
self.upcast::<GlobalScope>().clear_timeout_or_interval(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
||||||
fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Window(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::FunctionTimerCallback(callback),
|
TimerCallback::FunctionTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::Interval,
|
IsInterval::Interval)
|
||||||
TimerSource::FromWindow(self.upcast::<GlobalScope>().pipeline_id()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
||||||
fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Window(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::StringTimerCallback(callback),
|
TimerCallback::StringTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::Interval,
|
IsInterval::Interval)
|
||||||
TimerSource::FromWindow(self.upcast::<GlobalScope>().pipeline_id()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
|
||||||
|
@ -1341,7 +1336,7 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
||||||
self.timers.fire_timer(timer_id, self);
|
self.upcast::<GlobalScope>().fire_timer(timer_id);
|
||||||
self.reflow(ReflowGoal::ForDisplay,
|
self.reflow(ReflowGoal::ForDisplay,
|
||||||
ReflowQueryType::NoQuery,
|
ReflowQueryType::NoQuery,
|
||||||
ReflowReason::Timer);
|
ReflowReason::Timer);
|
||||||
|
@ -1371,16 +1366,6 @@ impl Window {
|
||||||
&self.layout_chan
|
&self.layout_chan
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schedule_callback(&self, callback: OneshotTimerCallback, duration: MsDuration) -> OneshotTimerHandle {
|
|
||||||
self.timers.schedule_callback(callback,
|
|
||||||
duration,
|
|
||||||
TimerSource::FromWindow(self.upcast::<GlobalScope>().pipeline_id()))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unschedule_callback(&self, handle: OneshotTimerHandle) {
|
|
||||||
self.timers.unschedule_callback(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn windowproxy_handler(&self) -> WindowProxyHandler {
|
pub fn windowproxy_handler(&self) -> WindowProxyHandler {
|
||||||
WindowProxyHandler(self.dom_static.windowproxy_handler.0)
|
WindowProxyHandler(self.dom_static.windowproxy_handler.0)
|
||||||
}
|
}
|
||||||
|
@ -1436,25 +1421,13 @@ impl Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thaw(&self) {
|
pub fn thaw(&self) {
|
||||||
self.timers.resume();
|
self.upcast::<GlobalScope>().resume();
|
||||||
|
|
||||||
// Push the document title to the compositor since we are
|
// Push the document title to the compositor since we are
|
||||||
// activating this document due to a navigation.
|
// activating this document due to a navigation.
|
||||||
self.Document().title_changed();
|
self.Document().title_changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn freeze(&self) {
|
|
||||||
self.timers.suspend();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn slow_down_timers(&self) {
|
|
||||||
self.timers.slow_down();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn speed_up_timers(&self) {
|
|
||||||
self.timers.speed_up();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn need_emit_timeline_marker(&self, timeline_type: TimelineMarkerType) -> bool {
|
pub fn need_emit_timeline_marker(&self, timeline_type: TimelineMarkerType) -> bool {
|
||||||
let markers = self.devtools_markers.borrow();
|
let markers = self.devtools_markers.borrow();
|
||||||
markers.contains(&timeline_type)
|
markers.contains(&timeline_type)
|
||||||
|
@ -1579,8 +1552,9 @@ impl Window {
|
||||||
mem_profiler_chan,
|
mem_profiler_chan,
|
||||||
time_profiler_chan,
|
time_profiler_chan,
|
||||||
constellation_chan,
|
constellation_chan,
|
||||||
scheduler_chan.clone(),
|
scheduler_chan,
|
||||||
resource_threads),
|
resource_threads,
|
||||||
|
timer_event_chan),
|
||||||
script_chan: script_chan,
|
script_chan: script_chan,
|
||||||
dom_manipulation_task_source: dom_task_source,
|
dom_manipulation_task_source: dom_task_source,
|
||||||
user_interaction_task_source: user_task_source,
|
user_interaction_task_source: user_task_source,
|
||||||
|
@ -1599,7 +1573,6 @@ impl Window {
|
||||||
session_storage: Default::default(),
|
session_storage: Default::default(),
|
||||||
local_storage: Default::default(),
|
local_storage: Default::default(),
|
||||||
status: DOMRefCell::new(DOMString::new()),
|
status: DOMRefCell::new(DOMString::new()),
|
||||||
timers: OneshotTimers::new(timer_event_chan, scheduler_chan),
|
|
||||||
parent_info: parent_info,
|
parent_info: parent_info,
|
||||||
dom_static: GlobalStaticData::new(),
|
dom_static: GlobalStaticData::new(),
|
||||||
js_runtime: DOMRefCell::new(Some(runtime.clone())),
|
js_runtime: DOMRefCell::new(Some(runtime.clone())),
|
||||||
|
|
|
@ -34,7 +34,7 @@ use net_traits::{LoadContext, load_whole_resource};
|
||||||
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, maybe_take_panic_result};
|
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, maybe_take_panic_result};
|
||||||
use script_runtime::{ScriptThreadEventCategory, PromiseJobQueue, EnqueuedPromiseCallback};
|
use script_runtime::{ScriptThreadEventCategory, PromiseJobQueue, EnqueuedPromiseCallback};
|
||||||
use script_thread::{Runnable, RunnableWrapper};
|
use script_thread::{Runnable, RunnableWrapper};
|
||||||
use script_traits::{MsDuration, TimerEvent, TimerEventId, TimerSource};
|
use script_traits::{TimerEvent, TimerEventId};
|
||||||
use script_traits::WorkerGlobalScopeInit;
|
use script_traits::WorkerGlobalScopeInit;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
|
@ -43,7 +43,7 @@ use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use task_source::file_reading::FileReadingTaskSource;
|
use task_source::file_reading::FileReadingTaskSource;
|
||||||
use timers::{IsInterval, OneshotTimerCallback, OneshotTimerHandle, OneshotTimers, TimerCallback};
|
use timers::{IsInterval, TimerCallback};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub fn prepare_workerscope_init(global: &GlobalScope,
|
pub fn prepare_workerscope_init(global: &GlobalScope,
|
||||||
|
@ -76,7 +76,6 @@ pub struct WorkerGlobalScope {
|
||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
location: MutNullableHeap<JS<WorkerLocation>>,
|
location: MutNullableHeap<JS<WorkerLocation>>,
|
||||||
navigator: MutNullableHeap<JS<WorkerNavigator>>,
|
navigator: MutNullableHeap<JS<WorkerNavigator>>,
|
||||||
timers: OneshotTimers,
|
|
||||||
|
|
||||||
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
#[ignore_heap_size_of = "Defined in ipc-channel"]
|
||||||
/// Optional `IpcSender` for sending the `DevtoolScriptControlMsg`
|
/// Optional `IpcSender` for sending the `DevtoolScriptControlMsg`
|
||||||
|
@ -107,15 +106,15 @@ impl WorkerGlobalScope {
|
||||||
init.mem_profiler_chan,
|
init.mem_profiler_chan,
|
||||||
init.time_profiler_chan,
|
init.time_profiler_chan,
|
||||||
init.constellation_chan,
|
init.constellation_chan,
|
||||||
init.scheduler_chan.clone(),
|
init.scheduler_chan,
|
||||||
init.resource_threads),
|
init.resource_threads,
|
||||||
|
timer_event_chan),
|
||||||
worker_id: init.worker_id,
|
worker_id: init.worker_id,
|
||||||
worker_url: worker_url,
|
worker_url: worker_url,
|
||||||
closing: closing,
|
closing: closing,
|
||||||
runtime: runtime,
|
runtime: runtime,
|
||||||
location: Default::default(),
|
location: Default::default(),
|
||||||
navigator: Default::default(),
|
navigator: Default::default(),
|
||||||
timers: OneshotTimers::new(timer_event_chan, init.scheduler_chan),
|
|
||||||
from_devtools_sender: init.from_devtools_sender,
|
from_devtools_sender: init.from_devtools_sender,
|
||||||
from_devtools_receiver: from_devtools_receiver,
|
from_devtools_receiver: from_devtools_receiver,
|
||||||
promise_job_queue: PromiseJobQueue::new(),
|
promise_job_queue: PromiseJobQueue::new(),
|
||||||
|
@ -130,16 +129,6 @@ impl WorkerGlobalScope {
|
||||||
&self.from_devtools_receiver
|
&self.from_devtools_receiver
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn schedule_callback(&self, callback: OneshotTimerCallback, duration: MsDuration) -> OneshotTimerHandle {
|
|
||||||
self.timers.schedule_callback(callback,
|
|
||||||
duration,
|
|
||||||
TimerSource::FromWorker)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn unschedule_callback(&self, handle: OneshotTimerHandle) {
|
|
||||||
self.timers.unschedule_callback(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn runtime(&self) -> *mut JSRuntime {
|
pub fn runtime(&self) -> *mut JSRuntime {
|
||||||
self.runtime.rt()
|
self.runtime.rt()
|
||||||
}
|
}
|
||||||
|
@ -281,49 +270,45 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope {
|
||||||
base64_atob(atob)
|
base64_atob(atob)
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
||||||
fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetTimeout(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Worker(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::FunctionTimerCallback(callback),
|
TimerCallback::FunctionTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::NonInterval,
|
IsInterval::NonInterval)
|
||||||
TimerSource::FromWorker)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout
|
||||||
fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetTimeout_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Worker(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::StringTimerCallback(callback),
|
TimerCallback::StringTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::NonInterval,
|
IsInterval::NonInterval)
|
||||||
TimerSource::FromWorker)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-cleartimeout
|
||||||
fn ClearTimeout(&self, handle: i32) {
|
fn ClearTimeout(&self, handle: i32) {
|
||||||
self.timers.clear_timeout_or_interval(GlobalRef::Worker(self), handle);
|
self.upcast::<GlobalScope>().clear_timeout_or_interval(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
||||||
fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetInterval(&self, _cx: *mut JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Worker(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::FunctionTimerCallback(callback),
|
TimerCallback::FunctionTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::Interval,
|
IsInterval::Interval)
|
||||||
TimerSource::FromWorker)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval
|
||||||
fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
fn SetInterval_(&self, _cx: *mut JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>) -> i32 {
|
||||||
self.timers.set_timeout_or_interval(GlobalRef::Worker(self),
|
self.upcast::<GlobalScope>().set_timeout_or_interval(
|
||||||
TimerCallback::StringTimerCallback(callback),
|
TimerCallback::StringTimerCallback(callback),
|
||||||
args,
|
args,
|
||||||
timeout,
|
timeout,
|
||||||
IsInterval::Interval,
|
IsInterval::Interval)
|
||||||
TimerSource::FromWorker)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
|
// https://html.spec.whatwg.org/multipage/#dom-windowtimers-clearinterval
|
||||||
|
@ -401,7 +386,7 @@ impl WorkerGlobalScope {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
|
||||||
self.timers.fire_timer(timer_id, self);
|
self.upcast::<GlobalScope>().fire_timer(timer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn close(&self) {
|
pub fn close(&self) {
|
||||||
|
|
|
@ -1077,15 +1077,14 @@ impl XMLHttpRequest {
|
||||||
xhr: Trusted::new(self),
|
xhr: Trusted::new(self),
|
||||||
generation_id: self.generation_id.get(),
|
generation_id: self.generation_id.get(),
|
||||||
});
|
});
|
||||||
let global = self.global();
|
|
||||||
let duration = Length::new(duration_ms as u64);
|
let duration = Length::new(duration_ms as u64);
|
||||||
*self.timeout_cancel.borrow_mut() = Some(global.r().schedule_callback(callback, duration));
|
*self.timeout_cancel.borrow_mut() =
|
||||||
|
Some(self.global_scope().schedule_callback(callback, duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cancel_timeout(&self) {
|
fn cancel_timeout(&self) {
|
||||||
if let Some(handle) = self.timeout_cancel.borrow_mut().take() {
|
if let Some(handle) = self.timeout_cancel.borrow_mut().take() {
|
||||||
let global = self.global();
|
self.global_scope().unschedule_callback(handle);
|
||||||
global.r().unschedule_callback(handle);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1244,9 +1244,9 @@ impl ScriptThread {
|
||||||
if let Some(ref inner_context) = root_context.find(id) {
|
if let Some(ref inner_context) = root_context.find(id) {
|
||||||
let window = inner_context.active_window();
|
let window = inner_context.active_window();
|
||||||
if visible {
|
if visible {
|
||||||
window.speed_up_timers();
|
window.upcast::<GlobalScope>().speed_up_timers();
|
||||||
} else {
|
} else {
|
||||||
window.slow_down_timers();
|
window.upcast::<GlobalScope>().slow_down_timers();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1291,7 @@ impl ScriptThread {
|
||||||
if let Some(root_context) = self.browsing_context.get() {
|
if let Some(root_context) = self.browsing_context.get() {
|
||||||
if let Some(ref inner_context) = root_context.find(id) {
|
if let Some(ref inner_context) = root_context.find(id) {
|
||||||
let window = inner_context.active_window();
|
let window = inner_context.active_window();
|
||||||
window.freeze();
|
window.upcast::<GlobalScope>().suspend();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1805,7 +1805,7 @@ impl ScriptThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
if incomplete.is_frozen {
|
if incomplete.is_frozen {
|
||||||
window.freeze();
|
window.upcast::<GlobalScope>().suspend();
|
||||||
}
|
}
|
||||||
|
|
||||||
if !incomplete.is_visible {
|
if !incomplete.is_visible {
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
use dom::bindings::callback::ExceptionHandling::Report;
|
use dom::bindings::callback::ExceptionHandling::Report;
|
||||||
use dom::bindings::cell::DOMRefCell;
|
use dom::bindings::cell::DOMRefCell;
|
||||||
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
use dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||||
use dom::bindings::global::GlobalRef;
|
|
||||||
use dom::bindings::reflector::Reflectable;
|
use dom::bindings::reflector::Reflectable;
|
||||||
use dom::bindings::str::DOMString;
|
use dom::bindings::str::DOMString;
|
||||||
|
use dom::globalscope::GlobalScope;
|
||||||
use dom::testbinding::TestBindingCallback;
|
use dom::testbinding::TestBindingCallback;
|
||||||
use dom::xmlhttprequest::XHRTimeoutCallback;
|
use dom::xmlhttprequest::XHRTimeoutCallback;
|
||||||
use euclid::length::Length;
|
use euclid::length::Length;
|
||||||
|
@ -167,7 +167,7 @@ impl OneshotTimers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fire_timer<T: Reflectable>(&self, id: TimerEventId, this: &T) {
|
pub fn fire_timer(&self, id: TimerEventId, global: &GlobalScope) {
|
||||||
let expected_id = self.expected_event_id.get();
|
let expected_id = self.expected_event_id.get();
|
||||||
if expected_id != id {
|
if expected_id != id {
|
||||||
debug!("ignoring timer fire event {:?} (expected {:?})", id, expected_id);
|
debug!("ignoring timer fire event {:?} (expected {:?})", id, expected_id);
|
||||||
|
@ -200,7 +200,7 @@ impl OneshotTimers {
|
||||||
|
|
||||||
for timer in timers_to_run {
|
for timer in timers_to_run {
|
||||||
let callback = timer.callback;
|
let callback = timer.callback;
|
||||||
callback.invoke(this, &self.js_timers);
|
callback.invoke(global, &self.js_timers);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.schedule_timer_call();
|
self.schedule_timer_call();
|
||||||
|
@ -272,7 +272,7 @@ impl OneshotTimers {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_timeout_or_interval(&self,
|
pub fn set_timeout_or_interval(&self,
|
||||||
global: GlobalRef,
|
global: &GlobalScope,
|
||||||
callback: TimerCallback,
|
callback: TimerCallback,
|
||||||
arguments: Vec<HandleValue>,
|
arguments: Vec<HandleValue>,
|
||||||
timeout: i32,
|
timeout: i32,
|
||||||
|
@ -287,7 +287,7 @@ impl OneshotTimers {
|
||||||
source)
|
source)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_timeout_or_interval(&self, global: GlobalRef, handle: i32) {
|
pub fn clear_timeout_or_interval(&self, global: &GlobalScope, handle: i32) {
|
||||||
self.js_timers.clear_timeout_or_interval(global, handle)
|
self.js_timers.clear_timeout_or_interval(global, handle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -364,7 +364,7 @@ impl JsTimers {
|
||||||
|
|
||||||
// see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
|
// see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
|
||||||
pub fn set_timeout_or_interval(&self,
|
pub fn set_timeout_or_interval(&self,
|
||||||
global: GlobalRef,
|
global: &GlobalScope,
|
||||||
callback: TimerCallback,
|
callback: TimerCallback,
|
||||||
arguments: Vec<HandleValue>,
|
arguments: Vec<HandleValue>,
|
||||||
timeout: i32,
|
timeout: i32,
|
||||||
|
@ -414,7 +414,7 @@ impl JsTimers {
|
||||||
new_handle
|
new_handle
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_timeout_or_interval(&self, global: GlobalRef, handle: i32) {
|
pub fn clear_timeout_or_interval(&self, global: &GlobalScope, handle: i32) {
|
||||||
let mut active_timers = self.active_timers.borrow_mut();
|
let mut active_timers = self.active_timers.borrow_mut();
|
||||||
|
|
||||||
if let Some(entry) = active_timers.remove(&JsTimerHandle(handle)) {
|
if let Some(entry) = active_timers.remove(&JsTimerHandle(handle)) {
|
||||||
|
@ -441,7 +441,7 @@ impl JsTimers {
|
||||||
}
|
}
|
||||||
|
|
||||||
// see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
|
// see https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
|
||||||
fn initialize_and_schedule(&self, global: GlobalRef, mut task: JsTimerTask) {
|
fn initialize_and_schedule(&self, global: &GlobalScope, mut task: JsTimerTask) {
|
||||||
let handle = task.handle;
|
let handle = task.handle;
|
||||||
let mut active_timers = self.active_timers.borrow_mut();
|
let mut active_timers = self.active_timers.borrow_mut();
|
||||||
|
|
||||||
|
@ -514,7 +514,7 @@ impl JsTimerTask {
|
||||||
// reschedule repeating timers when they were not canceled as part of step 4.2.
|
// reschedule repeating timers when they were not canceled as part of step 4.2.
|
||||||
if self.is_interval == IsInterval::Interval &&
|
if self.is_interval == IsInterval::Interval &&
|
||||||
timers.active_timers.borrow().contains_key(&self.handle) {
|
timers.active_timers.borrow().contains_key(&self.handle) {
|
||||||
timers.initialize_and_schedule(this.global().r(), self);
|
timers.initialize_and_schedule(&this.global_scope(), self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue