diff options
-rw-r--r-- | components/constellation/constellation.rs | 9 | ||||
-rw-r--r-- | components/constellation/pipeline.rs | 6 | ||||
-rw-r--r-- | components/constellation/timer_scheduler.rs | 17 | ||||
-rw-r--r-- | components/script/dom/globalscope.rs | 8 | ||||
-rw-r--r-- | components/script/dom/window.rs | 4 | ||||
-rw-r--r-- | components/script/script_thread.rs | 4 | ||||
-rw-r--r-- | components/script/timers.rs | 9 | ||||
-rw-r--r-- | components/script_traits/lib.rs | 13 |
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 |