mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
Terminate timer scheduler thread during shutdown
This commit is contained in:
parent
6a795f4795
commit
fb878f33d1
8 changed files with 47 additions and 23 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue