Skip to content

Commit 8dca100

Browse files
author
bors-servo
committed
Auto merge of #8237 - pcwalton:e10s-timer-events, r=jdm
script: Make timer events e10s-safe. Closes #8235. r? @jdm <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8237) <!-- Reviewable:end -->
2 parents 94ca87e + 587717b commit 8dca100

File tree

13 files changed

+70
-99
lines changed

13 files changed

+70
-99
lines changed

components/compositing/constellation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ pub struct Constellation<LTF, STF> {
138138
/// A list of in-process senders to `WebGLPaintTask`s.
139139
webgl_paint_tasks: Vec<Sender<CanvasMsg>>,
140140

141-
scheduler_chan: Sender<TimerEventRequest>,
141+
scheduler_chan: IpcSender<TimerEventRequest>,
142142
}
143143

144144
/// State needed to construct a constellation.

components/compositing/pipeline.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ pub struct CompositionPipeline {
6868
}
6969

7070
/// Initial setup data needed to construct a pipeline.
71+
///
72+
/// *DO NOT* add any Senders to this unless you absolutely know what you're doing, or pcwalton will
73+
/// have to rewrite your code. Use IPC senders instead.
7174
pub struct InitialPipelineState {
7275
/// The ID of the pipeline to create.
7376
pub id: PipelineId,
@@ -77,7 +80,7 @@ pub struct InitialPipelineState {
7780
/// A channel to the associated constellation.
7881
pub constellation_chan: ConstellationChan,
7982
/// A channel to schedule timer events.
80-
pub scheduler_chan: Sender<TimerEventRequest>,
83+
pub scheduler_chan: IpcSender<TimerEventRequest>,
8184
/// A channel to the compositor.
8285
pub compositor_proxy: Box<CompositorProxy + 'static + Send>,
8386
/// A channel to the developer tools, if applicable.
@@ -320,7 +323,7 @@ pub struct PipelineContent {
320323
id: PipelineId,
321324
parent_info: Option<(PipelineId, SubpageId)>,
322325
constellation_chan: ConstellationChan,
323-
scheduler_chan: Sender<TimerEventRequest>,
326+
scheduler_chan: IpcSender<TimerEventRequest>,
324327
compositor_proxy: Box<CompositorProxy + Send + 'static>,
325328
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
326329
image_cache_task: ImageCacheTask,

components/compositing/timer_scheduler.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
use euclid::length::Length;
6+
use ipc_channel::ipc::{self, IpcSender};
7+
use ipc_channel::router::ROUTER;
68
use num::traits::Saturating;
79
use script_traits::{MsDuration, NsDuration, precise_time_ms, precise_time_ns};
810
use script_traits::{TimerEvent, TimerEventRequest};
@@ -11,7 +13,7 @@ use std::cmp::{self, Ord};
1113
use std::collections::BinaryHeap;
1214
use std::sync::Arc;
1315
use std::sync::atomic::{self, AtomicBool};
14-
use std::sync::mpsc::{channel, Receiver, Select, Sender};
16+
use std::sync::mpsc::{channel, Receiver, Select};
1517
use std::thread::{self, spawn, Thread};
1618
use util::task::spawn_named;
1719

@@ -107,11 +109,11 @@ enum Task {
107109
}
108110

109111
impl TimerScheduler {
110-
pub fn start() -> Sender<TimerEventRequest> {
111-
let (chan, port) = channel();
112+
pub fn start() -> IpcSender<TimerEventRequest> {
113+
let (chan, port) = ipc::channel().unwrap();
112114

113115
let timer_scheduler = TimerScheduler {
114-
port: port,
116+
port: ROUTER.route_ipc_receiver_to_new_mpsc_receiver(port),
115117

116118
scheduled_events: RefCell::new(BinaryHeap::new()),
117119

@@ -126,6 +128,7 @@ impl TimerScheduler {
126128
}
127129

128130
fn run_event_loop(&self) {
131+
129132
loop {
130133
match self.receive_next_task() {
131134
Some(Task::HandleRequest(request)) => self.handle_request(request),

components/msg/compositor_msg.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,4 @@ pub enum EventResult {
169169
DefaultAllowed,
170170
DefaultPrevented,
171171
}
172+

components/script/dom/bindings/global.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use net_traits::ResourceTask;
2323
use profile_traits::mem;
2424
use script_task::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptTask};
2525
use script_traits::TimerEventRequest;
26-
use std::sync::mpsc::Sender;
2726
use url::Url;
2827
use util::mem::HeapSizeOf;
2928

@@ -99,7 +98,7 @@ impl<'a> GlobalRef<'a> {
9998
}
10099

101100
/// Get the scheduler channel to request timer events.
102-
pub fn scheduler_chan(&self) -> Sender<TimerEventRequest> {
101+
pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
103102
match *self {
104103
GlobalRef::Window(window) => window.scheduler_chan(),
105104
GlobalRef::Worker(worker) => worker.scheduler_chan(),

components/script/dom/bindings/trace.rs

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use net_traits::storage_task::StorageType;
6060
use profile_traits::mem::ProfilerChan as MemProfilerChan;
6161
use profile_traits::time::ProfilerChan as TimeProfilerChan;
6262
use script_task::ScriptChan;
63-
use script_traits::{TimerEventChan, TimerEventId, TimerSource, UntrustedNodeAddress};
63+
use script_traits::{TimerEventId, TimerSource, UntrustedNodeAddress};
6464
use selectors::parser::PseudoElement;
6565
use serde::{Deserialize, Serialize};
6666
use smallvec::SmallVec;
@@ -316,13 +316,6 @@ impl JSTraceable for Box<ScriptChan + Send> {
316316
}
317317
}
318318

319-
impl JSTraceable for Box<TimerEventChan + Send> {
320-
#[inline]
321-
fn trace(&self, _trc: *mut JSTracer) {
322-
// Do nothing
323-
}
324-
}
325-
326319
impl JSTraceable for Box<FnBox(f64, )> {
327320
#[inline]
328321
fn trace(&self, _trc: *mut JSTracer) {

components/script/dom/dedicatedworkerglobalscope.rs

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use dom::messageevent::MessageEvent;
1919
use dom::worker::{SimpleWorkerErrorHandler, TrustedWorkerAddress, WorkerMessageHandler};
2020
use dom::workerglobalscope::WorkerGlobalScope;
2121
use dom::workerglobalscope::WorkerGlobalScopeInit;
22-
use ipc_channel::ipc::IpcReceiver;
22+
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
2323
use ipc_channel::router::ROUTER;
2424
use js::jsapi::{HandleValue, JSContext, RootedValue};
2525
use js::jsapi::{JSAutoCompartment, JSAutoRequest};
@@ -30,7 +30,7 @@ use net_traits::load_whole_resource;
3030
use rand::random;
3131
use script_task::ScriptTaskEventCategory::WorkerEvent;
3232
use script_task::{ScriptTask, ScriptChan, ScriptPort, StackRootTLS, CommonScriptMsg};
33-
use script_traits::{TimerEvent, TimerEventChan, TimerSource};
33+
use script_traits::{TimerEvent, TimerSource};
3434
use std::mem::replace;
3535
use std::rc::Rc;
3636
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
@@ -102,29 +102,6 @@ impl ScriptPort for Receiver<(TrustedWorkerAddress, WorkerScriptMsg)> {
102102
}
103103
}
104104

105-
/// A TimerEventChan that can be cloned freely and will silently send a TrustedWorkerAddress
106-
/// with timer events. While this SendableWorkerScriptChan is alive, the associated Worker
107-
/// object will remain alive.
108-
struct WorkerThreadTimerEventChan {
109-
sender: Sender<(TrustedWorkerAddress, TimerEvent)>,
110-
worker: TrustedWorkerAddress,
111-
}
112-
113-
impl TimerEventChan for WorkerThreadTimerEventChan {
114-
fn send(&self, event: TimerEvent) -> Result<(), ()> {
115-
self.sender
116-
.send((self.worker.clone(), event))
117-
.map_err(|_| ())
118-
}
119-
120-
fn clone(&self) -> Box<TimerEventChan + Send> {
121-
box WorkerThreadTimerEventChan {
122-
sender: self.sender.clone(),
123-
worker: self.worker.clone(),
124-
}
125-
}
126-
}
127-
128105
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
129106
/// value for the duration of this object's lifetime. This ensures that the related Worker
130107
/// object only lives as long as necessary (ie. while events are being executed), while
@@ -182,7 +159,7 @@ impl DedicatedWorkerGlobalScope {
182159
parent_sender: Box<ScriptChan + Send>,
183160
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
184161
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
185-
timer_event_chan: Box<TimerEventChan + Send>,
162+
timer_event_chan: IpcSender<TimerEvent>,
186163
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>)
187164
-> DedicatedWorkerGlobalScope {
188165

@@ -206,7 +183,7 @@ impl DedicatedWorkerGlobalScope {
206183
parent_sender: Box<ScriptChan + Send>,
207184
own_sender: Sender<(TrustedWorkerAddress, WorkerScriptMsg)>,
208185
receiver: Receiver<(TrustedWorkerAddress, WorkerScriptMsg)>,
209-
timer_event_chan: Box<TimerEventChan + Send>,
186+
timer_event_chan: IpcSender<TimerEvent>,
210187
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>)
211188
-> Root<DedicatedWorkerGlobalScope> {
212189
let scope = box DedicatedWorkerGlobalScope::new_inherited(
@@ -248,15 +225,17 @@ impl DedicatedWorkerGlobalScope {
248225
ROUTER.route_ipc_receiver_to_mpsc_sender(from_devtools_receiver, devtools_mpsc_chan);
249226

250227
let (timer_tx, timer_rx) = channel();
251-
let timer_event_chan = box WorkerThreadTimerEventChan {
252-
sender: timer_tx,
253-
worker: worker.clone(),
254-
};
228+
let (timer_ipc_chan, timer_ipc_port) = ipc::channel().unwrap();
229+
let worker_for_route = worker.clone();
230+
ROUTER.add_route(timer_ipc_port.to_opaque(), box move |message| {
231+
let event = message.to().unwrap();
232+
timer_tx.send((worker_for_route.clone(), event)).unwrap();
233+
});
255234

256235
let global = DedicatedWorkerGlobalScope::new(
257236
init, url, id, devtools_mpsc_port, runtime.clone(),
258237
parent_sender.clone(), own_sender, receiver,
259-
timer_event_chan, timer_rx);
238+
timer_ipc_chan, timer_rx);
260239
// FIXME(njn): workers currently don't have a unique ID suitable for using in reporter
261240
// registration (#6631), so we instead use a random number and cross our fingers.
262241
let scope = global.upcast::<WorkerGlobalScope>();

components/script/dom/window.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ use page::Page;
5353
use profile_traits::mem;
5454
use rustc_serialize::base64::{FromBase64, STANDARD, ToBase64};
5555
use script_task::{ScriptChan, ScriptPort, MainThreadScriptMsg};
56-
use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan, MainThreadTimerEventChan};
57-
use script_traits::{ConstellationControlMsg, TimerEventChan, TimerEventId, TimerEventRequest, TimerSource};
56+
use script_task::{SendableMainThreadScriptChan, MainThreadScriptChan};
57+
use script_traits::{ConstellationControlMsg, TimerEvent, TimerEventId, TimerEventRequest};
58+
use script_traits::{TimerSource};
5859
use selectors::parser::PseudoElement;
5960
use std::ascii::AsciiExt;
6061
use std::borrow::ToOwned;
@@ -129,7 +130,7 @@ pub struct Window {
129130
session_storage: MutNullableHeap<JS<Storage>>,
130131
local_storage: MutNullableHeap<JS<Storage>>,
131132
#[ignore_heap_size_of = "channels are hard"]
132-
scheduler_chan: Sender<TimerEventRequest>,
133+
scheduler_chan: IpcSender<TimerEventRequest>,
133134
timers: ActiveTimers,
134135

135136
next_worker_id: Cell<WorkerId>,
@@ -1075,7 +1076,7 @@ impl Window {
10751076
self.constellation_chan.clone()
10761077
}
10771078

1078-
pub fn scheduler_chan(&self) -> Sender<TimerEventRequest> {
1079+
pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
10791080
self.scheduler_chan.clone()
10801081
}
10811082

@@ -1220,8 +1221,8 @@ impl Window {
12201221
mem_profiler_chan: mem::ProfilerChan,
12211222
devtools_chan: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
12221223
constellation_chan: ConstellationChan,
1223-
scheduler_chan: Sender<TimerEventRequest>,
1224-
timer_event_chan: MainThreadTimerEventChan,
1224+
scheduler_chan: IpcSender<TimerEventRequest>,
1225+
timer_event_chan: IpcSender<TimerEvent>,
12251226
layout_chan: LayoutChan,
12261227
id: PipelineId,
12271228
parent_info: Option<(PipelineId, SubpageId)>,
@@ -1255,7 +1256,7 @@ impl Window {
12551256
session_storage: Default::default(),
12561257
local_storage: Default::default(),
12571258
scheduler_chan: scheduler_chan.clone(),
1258-
timers: ActiveTimers::new(box timer_event_chan, scheduler_chan),
1259+
timers: ActiveTimers::new(timer_event_chan, scheduler_chan),
12591260
next_worker_id: Cell::new(WorkerId(0)),
12601261
id: id,
12611262
parent_info: parent_info,

components/script/dom/workerglobalscope.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ use msg::constellation_msg::{ConstellationChan, PipelineId, WorkerId};
2424
use net_traits::{ResourceTask, load_whole_resource};
2525
use profile_traits::mem;
2626
use script_task::{CommonScriptMsg, ScriptChan, ScriptPort};
27-
use script_traits::{TimerEventChan, TimerEventId, TimerEventRequest, TimerSource};
27+
use script_traits::{TimerEvent, TimerEventId, TimerEventRequest, TimerSource};
2828
use std::cell::Cell;
2929
use std::default::Default;
3030
use std::rc::Rc;
31-
use std::sync::mpsc::{Receiver, Sender};
31+
use std::sync::mpsc::Receiver;
3232
use timers::{ActiveTimers, IsInterval, TimerCallback};
3333
use url::{Url, UrlParser};
3434
use util::str::DOMString;
@@ -44,7 +44,7 @@ pub struct WorkerGlobalScopeInit {
4444
pub to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
4545
pub from_devtools_sender: Option<IpcSender<DevtoolScriptControlMsg>>,
4646
pub constellation_chan: ConstellationChan,
47-
pub scheduler_chan: Sender<TimerEventRequest>,
47+
pub scheduler_chan: IpcSender<TimerEventRequest>,
4848
pub worker_id: WorkerId,
4949
}
5050

@@ -87,15 +87,15 @@ pub struct WorkerGlobalScope {
8787
constellation_chan: ConstellationChan,
8888

8989
#[ignore_heap_size_of = "Defined in std"]
90-
scheduler_chan: Sender<TimerEventRequest>,
90+
scheduler_chan: IpcSender<TimerEventRequest>,
9191
}
9292

9393
impl WorkerGlobalScope {
9494
pub fn new_inherited(init: WorkerGlobalScopeInit,
9595
worker_url: Url,
9696
runtime: Rc<Runtime>,
9797
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
98-
timer_event_chan: Box<TimerEventChan + Send>)
98+
timer_event_chan: IpcSender<TimerEvent>)
9999
-> WorkerGlobalScope {
100100
WorkerGlobalScope {
101101
eventtarget: EventTarget::new_inherited(),
@@ -139,7 +139,7 @@ impl WorkerGlobalScope {
139139
self.constellation_chan.clone()
140140
}
141141

142-
pub fn scheduler_chan(&self) -> Sender<TimerEventRequest> {
142+
pub fn scheduler_chan(&self) -> IpcSender<TimerEventRequest> {
143143
self.scheduler_chan.clone()
144144
}
145145

components/script/script_task.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ use script_traits::CompositorEvent::{TouchDownEvent, TouchMoveEvent, TouchUpEven
8383
use script_traits::{CompositorEvent, ConstellationControlMsg};
8484
use script_traits::{InitialScriptState, MouseButton, NewLayoutInfo};
8585
use script_traits::{OpaqueScriptLayoutChannel, ScriptState, ScriptTaskFactory};
86-
use script_traits::{TimerEvent, TimerEventChan, TimerEventRequest, TimerSource};
86+
use script_traits::{TimerEvent, TimerEventRequest, TimerSource};
8787
use std::any::Any;
8888
use std::borrow::ToOwned;
8989
use std::cell::{Cell, RefCell};
@@ -320,20 +320,6 @@ impl MainThreadScriptChan {
320320
}
321321
}
322322

323-
pub struct MainThreadTimerEventChan(Sender<TimerEvent>);
324-
325-
impl TimerEventChan for MainThreadTimerEventChan {
326-
fn send(&self, event: TimerEvent) -> Result<(), ()> {
327-
let MainThreadTimerEventChan(ref chan) = *self;
328-
chan.send(event).map_err(|_| ())
329-
}
330-
331-
fn clone(&self) -> Box<TimerEventChan + Send> {
332-
let MainThreadTimerEventChan(ref chan) = *self;
333-
box MainThreadTimerEventChan((*chan).clone())
334-
}
335-
}
336-
337323
pub struct StackRootTLS;
338324

339325
impl StackRootTLS {
@@ -416,7 +402,7 @@ pub struct ScriptTask {
416402
/// List of pipelines that have been owned and closed by this script task.
417403
closed_pipelines: RefCell<HashSet<PipelineId>>,
418404

419-
scheduler_chan: Sender<TimerEventRequest>,
405+
scheduler_chan: IpcSender<TimerEventRequest>,
420406
timer_event_chan: Sender<TimerEvent>,
421407
timer_event_port: Receiver<TimerEvent>,
422408
}
@@ -1583,6 +1569,10 @@ impl ScriptTask {
15831569
let mut page_remover = AutoPageRemover::new(self, page_to_remove);
15841570
let MainThreadScriptChan(ref sender) = self.chan;
15851571

1572+
let (ipc_timer_event_chan, ipc_timer_event_port) = ipc::channel().unwrap();
1573+
ROUTER.route_ipc_receiver_to_mpsc_sender(ipc_timer_event_port,
1574+
self.timer_event_chan.clone());
1575+
15861576
// Create the window and document objects.
15871577
let window = Window::new(self.js_runtime.clone(),
15881578
page.clone(),
@@ -1597,7 +1587,7 @@ impl ScriptTask {
15971587
self.devtools_chan.clone(),
15981588
self.constellation_chan.clone(),
15991589
self.scheduler_chan.clone(),
1600-
MainThreadTimerEventChan(self.timer_event_chan.clone()),
1590+
ipc_timer_event_chan,
16011591
incomplete.layout_chan,
16021592
incomplete.pipeline_id,
16031593
incomplete.parent_info,

0 commit comments

Comments
 (0)