aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/constellation/constellation.rs9
-rw-r--r--components/constellation/pipeline.rs6
-rw-r--r--components/constellation/timer_scheduler.rs17
-rw-r--r--components/script/dom/globalscope.rs8
-rw-r--r--components/script/dom/window.rs4
-rw-r--r--components/script/script_thread.rs4
-rw-r--r--components/script/timers.rs9
-rw-r--r--components/script_traits/lib.rs13
8 files changed, 47 insertions, 23 deletions
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index 109e8bfd59e..30f36cbaa02 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -96,7 +96,7 @@ use profile_traits::time;
use script_traits::{AnimationState, AnimationTickType, CompositorEvent};
use script_traits::{ConstellationControlMsg, ConstellationMsg as FromCompositorMsg, DiscardBrowsingContext};
use script_traits::{DocumentActivity, DocumentState, LayoutControlMsg, LoadData};
-use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerEventRequest};
+use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, IFrameSandboxState, TimerSchedulerMsg};
use script_traits::{LayoutMsg as FromLayoutMsg, ScriptMsg as FromScriptMsg, ScriptThreadFactory};
use script_traits::{LogEntry, ServiceWorkerMsg, webdriver_msg};
use script_traits::{MozBrowserErrorType, MozBrowserEvent, WebDriverCommandMsg, WindowSizeData};
@@ -214,7 +214,7 @@ pub struct Constellation<Message, LTF, STF> {
/// A channel for the constellation to send messages to the
/// timer thread.
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// A channel for the constellation to send messages to the
/// Webrender thread.
@@ -1241,6 +1241,11 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}
}
+ debug!("Exiting timer scheduler.");
+ if let Err(e) = self.scheduler_chan.send(TimerSchedulerMsg::Exit) {
+ warn!("Exit timer scheduler failed ({})", e);
+ }
+
debug!("Exiting font cache thread.");
self.font_cache_thread.exit();
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index 8570e98ef5a..aa380a8e5c1 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -25,7 +25,7 @@ use script_traits::{ConstellationControlMsg, DevicePixel, DiscardBrowsingContext
use script_traits::{DocumentActivity, InitialScriptState};
use script_traits::{LayoutControlMsg, LayoutMsg, LoadData, MozBrowserEvent};
use script_traits::{NewLayoutInfo, SWManagerMsg, SWManagerSenders, ScriptMsg};
-use script_traits::{ScriptThreadFactory, TimerEventRequest, WindowSizeData};
+use script_traits::{ScriptThreadFactory, TimerSchedulerMsg, WindowSizeData};
use servo_config::opts::{self, Opts};
use servo_config::prefs::{PREFS, Pref};
use servo_url::ServoUrl;
@@ -121,7 +121,7 @@ pub struct InitialPipelineState {
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
/// A channel to schedule timer events.
- pub scheduler_chan: IpcSender<TimerEventRequest>,
+ pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// A channel to the compositor.
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
@@ -445,7 +445,7 @@ pub struct UnprivilegedPipelineContent {
parent_info: Option<(PipelineId, FrameType)>,
constellation_chan: IpcSender<ScriptMsg>,
layout_to_constellation_chan: IpcSender<LayoutMsg>,
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
bluetooth_thread: IpcSender<BluetoothRequest>,
swmanager_thread: IpcSender<SWManagerMsg>,
diff --git a/components/constellation/timer_scheduler.rs b/components/constellation/timer_scheduler.rs
index 832773f0d71..2ed0005957e 100644
--- a/components/constellation/timer_scheduler.rs
+++ b/components/constellation/timer_scheduler.rs
@@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use ipc_channel::ipc::{self, IpcSender};
-use script_traits::{TimerEvent, TimerEventRequest};
+use script_traits::{TimerEvent, TimerEventRequest, TimerSchedulerMsg};
use std::cmp::{self, Ord};
use std::collections::BinaryHeap;
use std::sync::mpsc;
@@ -38,7 +38,7 @@ impl PartialEq for ScheduledEvent {
}
impl TimerScheduler {
- pub fn start() -> IpcSender<TimerEventRequest> {
+ pub fn start() -> IpcSender<TimerSchedulerMsg> {
let (req_ipc_sender, req_ipc_receiver) = ipc::channel().expect("Channel creation failed.");
let (req_sender, req_receiver) = mpsc::sync_channel(1);
@@ -72,7 +72,7 @@ impl TimerScheduler {
// Look to see if there are any incoming events
match req_receiver.try_recv() {
// If there is an event, add it to the priority queue
- Ok(req) => {
+ Ok(TimerSchedulerMsg::Request(req)) => {
let TimerEventRequest(_, _, _, delay) = req;
let schedule = Instant::now() + Duration::from_millis(delay.get());
let event = ScheduledEvent { request: req, for_time: schedule };
@@ -85,7 +85,8 @@ impl TimerScheduler {
None => thread::park(),
Some(event) => thread::park_timeout(event.for_time - now),
},
- // If the channel is closed, we are done.
+ // If the channel is closed or we are shutting down, we are done.
+ Ok(TimerSchedulerMsg::Exit) |
Err(Disconnected) => break,
}
}
@@ -105,8 +106,16 @@ impl TimerScheduler {
.name(String::from("TimerProxy"))
.spawn(move || {
while let Ok(req) = req_ipc_receiver.recv() {
+ let mut shutting_down = false;
+ match req {
+ TimerSchedulerMsg::Exit => shutting_down = true,
+ _ => {}
+ }
let _ = req_sender.send(req);
timeout_thread.unpark();
+ if shutting_down {
+ break;
+ }
}
// This thread can terminate if the req_ipc_sender is dropped.
warn!("TimerProxy thread terminated.");
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index 2b4d3fc6886..73ba61e4557 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -37,7 +37,7 @@ use profile_traits::{mem, time};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread};
use script_traits::{MsDuration, ScriptMsg as ConstellationMsg, TimerEvent};
-use script_traits::{TimerEventId, TimerEventRequest, TimerSource};
+use script_traits::{TimerEventId, TimerSchedulerMsg, TimerSource};
use servo_url::ServoUrl;
use std::cell::Cell;
use std::collections::HashMap;
@@ -82,7 +82,7 @@ pub struct GlobalScope {
constellation_chan: IpcSender<ConstellationMsg>,
#[ignore_heap_size_of = "channels are hard"]
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// https://html.spec.whatwg.org/multipage/#in-error-reporting-mode
in_error_reporting_mode: Cell<bool>,
@@ -101,7 +101,7 @@ impl GlobalScope {
mem_profiler_chan: mem::ProfilerChan,
time_profiler_chan: time::ProfilerChan,
constellation_chan: IpcSender<ConstellationMsg>,
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
resource_threads: ResourceThreads,
timer_event_chan: IpcSender<TimerEvent>)
-> Self {
@@ -229,7 +229,7 @@ impl GlobalScope {
&self.constellation_chan
}
- pub fn scheduler_chan(&self) -> &IpcSender<TimerEventRequest> {
+ pub fn scheduler_chan(&self) -> &IpcSender<TimerSchedulerMsg> {
&self.scheduler_chan
}
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index a21d09c97ec..6a264c86d6b 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -80,7 +80,7 @@ use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable, Runnabl
use script_thread::{SendableMainThreadScriptChan, ImageCacheMsg};
use script_traits::{ConstellationControlMsg, LoadData, MozBrowserEvent, UntrustedNodeAddress};
use script_traits::{DocumentState, TimerEvent, TimerEventId};
-use script_traits::{ScriptMsg as ConstellationMsg, TimerEventRequest, WindowSizeData, WindowSizeType};
+use script_traits::{ScriptMsg as ConstellationMsg, TimerSchedulerMsg, WindowSizeData, WindowSizeType};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use servo_atoms::Atom;
use servo_config::opts;
@@ -1711,7 +1711,7 @@ impl Window {
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
constellation_chan: IpcSender<ConstellationMsg>,
control_chan: IpcSender<ConstellationControlMsg>,
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
timer_event_chan: IpcSender<TimerEvent>,
layout_chan: Sender<Msg>,
id: PipelineId,
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 4399fb32630..87cf0920b5e 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -86,7 +86,7 @@ use script_traits::{CompositorEvent, ConstellationControlMsg};
use script_traits::{DocumentActivity, DiscardBrowsingContext, EventResult};
use script_traits::{InitialScriptState, LayoutMsg, LoadData, MouseButton, MouseEventType, MozBrowserEvent};
use script_traits::{NewLayoutInfo, ScriptMsg as ConstellationMsg};
-use script_traits::{ScriptThreadFactory, TimerEvent, TimerEventRequest, TimerSource};
+use script_traits::{ScriptThreadFactory, TimerEvent, TimerSchedulerMsg, TimerSource};
use script_traits::{TouchEventType, TouchId, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent, ResizeEvent};
use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent};
@@ -472,7 +472,7 @@ pub struct ScriptThread {
/// List of pipelines that have been owned and closed by this script thread.
closed_pipelines: DOMRefCell<HashSet<PipelineId>>,
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
timer_event_chan: Sender<TimerEvent>,
timer_event_port: Receiver<TimerEvent>,
diff --git a/components/script/timers.rs b/components/script/timers.rs
index c90a3fa5b1d..cccefd5eb77 100644
--- a/components/script/timers.rs
+++ b/components/script/timers.rs
@@ -18,7 +18,8 @@ use ipc_channel::ipc::IpcSender;
use js::jsapi::{HandleValue, Heap};
use js::jsval::{JSVal, UndefinedValue};
use script_traits::{MsDuration, precise_time_ms};
-use script_traits::{TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
+use script_traits::{TimerEvent, TimerEventId, TimerEventRequest};
+use script_traits::{TimerSchedulerMsg, TimerSource};
use servo_config::prefs::PREFS;
use std::cell::Cell;
use std::cmp::{self, Ord, Ordering};
@@ -35,7 +36,7 @@ pub struct OneshotTimers {
#[ignore_heap_size_of = "Defined in std"]
timer_event_chan: IpcSender<TimerEvent>,
#[ignore_heap_size_of = "Defined in std"]
- scheduler_chan: IpcSender<TimerEventRequest>,
+ scheduler_chan: IpcSender<TimerSchedulerMsg>,
next_timer_handle: Cell<OneshotTimerHandle>,
timers: DOMRefCell<Vec<OneshotTimer>>,
suspended_since: Cell<Option<MsDuration>>,
@@ -109,7 +110,7 @@ impl PartialEq for OneshotTimer {
impl OneshotTimers {
pub fn new(timer_event_chan: IpcSender<TimerEvent>,
- scheduler_chan: IpcSender<TimerEventRequest>)
+ scheduler_chan: IpcSender<TimerSchedulerMsg>)
-> OneshotTimers {
OneshotTimers {
js_timers: JsTimers::new(),
@@ -267,7 +268,7 @@ impl OneshotTimers {
let delay = Length::new(timer.scheduled_for.get().saturating_sub(precise_time_ms().get()));
let request = TimerEventRequest(self.timer_event_chan.clone(), timer.source,
expected_event_id, delay);
- self.scheduler_chan.send(request).unwrap();
+ self.scheduler_chan.send(TimerSchedulerMsg::Request(request)).unwrap();
}
}
diff --git a/components/script_traits/lib.rs b/components/script_traits/lib.rs
index 83a0437f240..0c4ac7b3fa3 100644
--- a/components/script_traits/lib.rs
+++ b/components/script_traits/lib.rs
@@ -416,6 +416,15 @@ pub enum TouchpadPressurePhase {
#[derive(Deserialize, Serialize)]
pub struct TimerEventRequest(pub IpcSender<TimerEvent>, pub TimerSource, pub TimerEventId, pub MsDuration);
+/// Type of messages that can be sent to the timer scheduler.
+#[derive(Deserialize, Serialize)]
+pub enum TimerSchedulerMsg {
+ /// Message to schedule a new timer event.
+ Request(TimerEventRequest),
+ /// Message to exit the timer scheduler.
+ Exit,
+}
+
/// Notifies the script thread to fire due timers.
/// `TimerSource` must be `FromWindow` when dispatched to `ScriptThread` and
/// must be `FromWorker` when dispatched to a `DedicatedGlobalWorkerScope`
@@ -479,7 +488,7 @@ pub struct InitialScriptState {
/// A sender for the layout thread to communicate to the constellation.
pub layout_to_constellation_chan: IpcSender<LayoutMsg>,
/// A channel to schedule timer events.
- pub scheduler_chan: IpcSender<TimerEventRequest>,
+ pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// A channel to the resource manager thread.
pub resource_threads: ResourceThreads,
/// A channel to the bluetooth thread.
@@ -770,7 +779,7 @@ pub struct WorkerGlobalScopeInit {
/// Messages to send to constellation
pub constellation_chan: IpcSender<ScriptMsg>,
/// Message to send to the scheduler
- pub scheduler_chan: IpcSender<TimerEventRequest>,
+ pub scheduler_chan: IpcSender<TimerSchedulerMsg>,
/// The worker id
pub worker_id: WorkerId,
/// The pipeline id