impl timer-task-source, dedicated time-out mechanism for service-worker

This commit is contained in:
Gregory Terzian 2019-11-17 14:37:45 +08:00
parent d553158e95
commit 50a7111eb6
13 changed files with 241 additions and 204 deletions

View file

@ -81,32 +81,27 @@ impl ScriptPort for Receiver<DedicatedWorkerScriptMsg> {
}
pub trait WorkerEventLoopMethods {
type TimerMsg: Send;
type WorkerMsg: QueuedTaskConversion + Send;
type Event;
fn timer_event_port(&self) -> &Receiver<Self::TimerMsg>;
fn task_queue(&self) -> &TaskQueue<Self::WorkerMsg>;
fn handle_event(&self, event: Self::Event);
fn handle_worker_post_event(&self, worker: &TrustedWorkerAddress) -> Option<AutoWorkerReset>;
fn from_worker_msg(&self, msg: Self::WorkerMsg) -> Self::Event;
fn from_timer_msg(&self, msg: Self::TimerMsg) -> Self::Event;
fn from_devtools_msg(&self, msg: DevtoolScriptControlMsg) -> Self::Event;
}
// https://html.spec.whatwg.org/multipage/#worker-event-loop
pub fn run_worker_event_loop<T, TimerMsg, WorkerMsg, Event>(
pub fn run_worker_event_loop<T, WorkerMsg, Event>(
worker_scope: &T,
worker: Option<&TrustedWorkerAddress>,
) where
TimerMsg: Send,
WorkerMsg: QueuedTaskConversion + Send,
T: WorkerEventLoopMethods<TimerMsg = TimerMsg, WorkerMsg = WorkerMsg, Event = Event>
T: WorkerEventLoopMethods<WorkerMsg = WorkerMsg, Event = Event>
+ DerivedFrom<WorkerGlobalScope>
+ DerivedFrom<GlobalScope>
+ DomObject,
{
let scope = worker_scope.upcast::<WorkerGlobalScope>();
let timer_event_port = worker_scope.timer_event_port();
let devtools_port = match scope.from_devtools_sender() {
Some(_) => Some(scope.from_devtools_receiver()),
None => None,
@ -117,7 +112,6 @@ pub fn run_worker_event_loop<T, TimerMsg, WorkerMsg, Event>(
task_queue.take_tasks(msg.unwrap());
worker_scope.from_worker_msg(task_queue.recv().unwrap())
},
recv(timer_event_port) -> msg => worker_scope.from_timer_msg(msg.unwrap()),
recv(devtools_port.unwrap_or(&crossbeam_channel::never())) -> msg =>
worker_scope.from_devtools_msg(msg.unwrap()),
};
@ -132,13 +126,10 @@ pub fn run_worker_event_loop<T, TimerMsg, WorkerMsg, Event>(
// Batch all events that are ready.
// The task queue will throttle non-priority tasks if necessary.
match task_queue.try_recv() {
Err(_) => match timer_event_port.try_recv() {
Err(_) => match devtools_port.map(|port| port.try_recv()) {
None => {},
Some(Err(_)) => break,
Some(Ok(ev)) => sequential.push(worker_scope.from_devtools_msg(ev)),
},
Ok(ev) => sequential.push(worker_scope.from_timer_msg(ev)),
Err(_) => match devtools_port.map(|port| port.try_recv()) {
None => {},
Some(Err(_)) => break,
Some(Ok(ev)) => sequential.push(worker_scope.from_devtools_msg(ev)),
},
Ok(ev) => sequential.push(worker_scope.from_worker_msg(ev)),
}

View file

@ -36,7 +36,7 @@ use crate::task_source::TaskSourceName;
use crossbeam_channel::{unbounded, Receiver, Sender};
use devtools_traits::DevtoolScriptControlMsg;
use dom_struct::dom_struct;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::ipc::IpcReceiver;
use ipc_channel::router::ROUTER;
use js::jsapi::JS_AddInterruptCallback;
use js::jsapi::{Heap, JSContext, JSObject};
@ -47,7 +47,7 @@ use net_traits::image_cache::ImageCache;
use net_traits::request::{CredentialsMode, Destination, ParserMetadata};
use net_traits::request::{Referrer, RequestBuilder, RequestMode};
use net_traits::IpcSend;
use script_traits::{TimerEvent, TimerSource, WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
use script_traits::{WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
use servo_rand::random;
use servo_url::ServoUrl;
use std::mem::replace;
@ -92,7 +92,6 @@ pub enum DedicatedWorkerScriptMsg {
pub enum MixedMessage {
FromWorker(DedicatedWorkerScriptMsg),
FromScheduler((TrustedWorkerAddress, TimerEvent)),
FromDevtools(DevtoolScriptControlMsg),
}
@ -173,8 +172,6 @@ pub struct DedicatedWorkerGlobalScope {
task_queue: TaskQueue<DedicatedWorkerScriptMsg>,
#[ignore_malloc_size_of = "Defined in std"]
own_sender: Sender<DedicatedWorkerScriptMsg>,
#[ignore_malloc_size_of = "Defined in std"]
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>,
#[ignore_malloc_size_of = "Trusted<T> has unclear ownership like Dom<T>"]
worker: DomRefCell<Option<TrustedWorkerAddress>>,
#[ignore_malloc_size_of = "Can't measure trait objects"]
@ -185,14 +182,9 @@ pub struct DedicatedWorkerGlobalScope {
}
impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope {
type TimerMsg = (TrustedWorkerAddress, TimerEvent);
type WorkerMsg = DedicatedWorkerScriptMsg;
type Event = MixedMessage;
fn timer_event_port(&self) -> &Receiver<(TrustedWorkerAddress, TimerEvent)> {
&self.timer_event_port
}
fn task_queue(&self) -> &TaskQueue<DedicatedWorkerScriptMsg> {
&self.task_queue
}
@ -210,10 +202,6 @@ impl WorkerEventLoopMethods for DedicatedWorkerGlobalScope {
MixedMessage::FromWorker(msg)
}
fn from_timer_msg(&self, msg: (TrustedWorkerAddress, TimerEvent)) -> MixedMessage {
MixedMessage::FromScheduler(msg)
}
fn from_devtools_msg(&self, msg: DevtoolScriptControlMsg) -> MixedMessage {
MixedMessage::FromDevtools(msg)
}
@ -230,8 +218,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender: Box<dyn ScriptChan + Send>,
own_sender: Sender<DedicatedWorkerScriptMsg>,
receiver: Receiver<DedicatedWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>,
closing: Arc<AtomicBool>,
image_cache: Arc<dyn ImageCache>,
) -> DedicatedWorkerGlobalScope {
@ -243,12 +229,10 @@ impl DedicatedWorkerGlobalScope {
worker_url,
runtime,
from_devtools_receiver,
timer_event_chan,
Some(closing),
),
task_queue: TaskQueue::new(receiver, own_sender.clone()),
own_sender: own_sender,
timer_event_port: timer_event_port,
parent_sender: parent_sender,
worker: DomRefCell::new(None),
image_cache: image_cache,
@ -266,8 +250,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender: Box<dyn ScriptChan + Send>,
own_sender: Sender<DedicatedWorkerScriptMsg>,
receiver: Receiver<DedicatedWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<(TrustedWorkerAddress, TimerEvent)>,
closing: Arc<AtomicBool>,
image_cache: Arc<dyn ImageCache>,
) -> DomRoot<DedicatedWorkerGlobalScope> {
@ -282,8 +264,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender,
own_sender,
receiver,
timer_event_chan,
timer_event_port,
closing,
image_cache,
));
@ -352,17 +332,6 @@ impl DedicatedWorkerGlobalScope {
devtools_mpsc_chan,
);
let (timer_tx, timer_rx) = unbounded();
let (timer_ipc_chan, timer_ipc_port) = ipc::channel().unwrap();
let worker_for_route = worker.clone();
ROUTER.add_route(
timer_ipc_port.to_opaque(),
Box::new(move |message| {
let event = message.to().unwrap();
timer_tx.send((worker_for_route.clone(), event)).unwrap();
}),
);
let global = DedicatedWorkerGlobalScope::new(
init,
DOMString::from_string(worker_name),
@ -373,8 +342,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender.clone(),
own_sender,
receiver,
timer_ipc_chan,
timer_rx,
closing,
image_cache,
);
@ -503,14 +470,6 @@ impl DedicatedWorkerGlobalScope {
},
_ => debug!("got an unusable devtools control message inside the worker!"),
},
MixedMessage::FromScheduler((linked_worker, timer_event)) => match timer_event {
TimerEvent(TimerSource::FromWorker, id) => {
let _ar = AutoWorkerReset::new(self, linked_worker);
let scope = self.upcast::<WorkerGlobalScope>();
scope.handle_fire_timer(id);
},
TimerEvent(_, _) => panic!("A worker received a TimerEvent from a window."),
},
MixedMessage::FromWorker(DedicatedWorkerScriptMsg::CommonWorker(
linked_worker,
msg,

View file

@ -15,7 +15,6 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::windowproxy::WindowProxy;
use crate::script_runtime::JSContext;
use dom_struct::dom_struct;
use ipc_channel::ipc;
use js::jsapi::{Heap, JSObject};
use js::jsval::{JSVal, UndefinedValue};
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
@ -48,8 +47,6 @@ impl DissimilarOriginWindow {
#[allow(unsafe_code)]
pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> DomRoot<Self> {
let cx = global_to_clone_from.get_cx();
// Any timer events fired on this window are ignored.
let (timer_event_chan, _) = ipc::channel().unwrap();
let win = Box::new(Self {
globalscope: GlobalScope::new_inherited(
PipelineId::new(),
@ -59,7 +56,6 @@ impl DissimilarOriginWindow {
global_to_clone_from.script_to_constellation_chan().clone(),
global_to_clone_from.scheduler_chan().clone(),
global_to_clone_from.resource_threads().clone(),
timer_event_chan,
global_to_clone_from.origin().clone(),
// FIXME(nox): The microtask queue is probably not important
// here, but this whole DOM interface is a hack anyway.

View file

@ -39,6 +39,7 @@ use crate::task_source::networking::NetworkingTaskSource;
use crate::task_source::performance_timeline::PerformanceTimelineTaskSource;
use crate::task_source::port_message::PortMessageQueue;
use crate::task_source::remote_event::RemoteEventTaskSource;
use crate::task_source::timer::TimerTaskSource;
use crate::task_source::websocket::WebsocketTaskSource;
use crate::task_source::TaskSource;
use crate::task_source::TaskSourceName;
@ -134,8 +135,13 @@ pub struct GlobalScope {
/// including resource_thread, filemanager_thread and storage_thread
resource_threads: ResourceThreads,
/// The mechanism by which time-outs and intervals are scheduled.
/// <https://html.spec.whatwg.org/multipage/#timers>
timers: OneshotTimers,
/// Have timers been initialized?
init_timers: Cell<bool>,
/// The origin of the globalscope
origin: MutableOrigin,
@ -188,6 +194,13 @@ struct MessageListener {
context: Trusted<GlobalScope>,
}
/// A wrapper between timer events coming in over IPC, and the event-loop.
struct TimerListener {
canceller: TaskCanceller,
task_source: TimerTaskSource,
context: Trusted<GlobalScope>,
}
/// Data representing a message-port managed by this global.
#[derive(JSTraceable, MallocSizeOf)]
pub enum ManagedMessagePort {
@ -212,6 +225,34 @@ pub enum MessagePortState {
UnManaged,
}
impl TimerListener {
/// Handle a timer-event coming-in over IPC,
/// by queuing the appropriate task on the relevant event-loop.
fn handle(&self, event: TimerEvent) {
let context = self.context.clone();
// Step 18, queue a task,
// https://html.spec.whatwg.org/multipage/#timer-initialisation-steps
let _ = self.task_source.queue_with_canceller(
task!(timer_event: move || {
let global = context.root();
let TimerEvent(source, id) = event;
match source {
TimerSource::FromWorker => {
global.downcast::<WorkerGlobalScope>().expect("Window timer delivered to worker");
},
TimerSource::FromWindow(pipeline) => {
assert_eq!(pipeline, global.pipeline_id());
global.downcast::<Window>().expect("Worker timer delivered to window");
},
};
// Step 7, substeps run in a task.
global.fire_timer(id);
}),
&self.canceller,
);
}
}
impl MessageListener {
/// A new message came in, handle it via a task enqueued on the event-loop.
/// A task is required, since we are using a trusted globalscope,
@ -297,7 +338,6 @@ impl GlobalScope {
script_to_constellation_chan: ScriptToConstellationChan,
scheduler_chan: IpcSender<TimerSchedulerMsg>,
resource_threads: ResourceThreads,
timer_event_chan: IpcSender<TimerEvent>,
origin: MutableOrigin,
microtask_queue: Rc<MicrotaskQueue>,
is_headless: bool,
@ -318,7 +358,8 @@ impl GlobalScope {
scheduler_chan: scheduler_chan.clone(),
in_error_reporting_mode: Default::default(),
resource_threads,
timers: OneshotTimers::new(timer_event_chan, scheduler_chan),
timers: OneshotTimers::new(scheduler_chan),
init_timers: Default::default(),
origin,
microtask_queue,
list_auto_close_worker: Default::default(),
@ -349,6 +390,36 @@ impl GlobalScope {
false
}
/// Setup the IPC-to-event-loop glue for timers to schedule themselves.
fn setup_timers(&self) {
if self.init_timers.get() {
return;
}
self.init_timers.set(true);
let (timer_ipc_chan, timer_ipc_port) = ipc::channel().unwrap();
self.timers.setup_scheduling(timer_ipc_chan);
// Setup route from IPC to task-queue for the timer-task-source.
let context = Trusted::new(&*self);
let (task_source, canceller) = (
self.timer_task_source(),
self.task_canceller(TaskSourceName::Timer),
);
let timer_listener = TimerListener {
context,
task_source,
canceller,
};
ROUTER.add_route(
timer_ipc_port.to_opaque(),
Box::new(move |message| {
let event = message.to().unwrap();
timer_listener.handle(event);
}),
);
}
/// Complete the transfer of a message-port.
fn complete_port_transfer(&self, port_id: MessagePortId, tasks: VecDeque<PortMessageTask>) {
let should_start = if let MessagePortState::Managed(_id, message_ports) =
@ -1063,6 +1134,18 @@ impl GlobalScope {
unreachable!();
}
/// `TaskSource` to send messages to the timer queue of
/// this global scope.
pub fn timer_task_source(&self) -> TimerTaskSource {
if let Some(window) = self.downcast::<Window>() {
return window.task_manager().timer_task_source();
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
return worker.timer_task_source();
}
unreachable!();
}
/// `TaskSource` to send messages to the remote-event task source of
/// this global scope.
pub fn remote_event_task_source(&self) -> RemoteEventTaskSource {
@ -1145,11 +1228,13 @@ impl GlobalScope {
)
}
/// <https://html.spec.whatwg.org/multipage/#timer-initialisation-steps>
pub fn schedule_callback(
&self,
callback: OneshotTimerCallback,
duration: MsDuration,
) -> OneshotTimerHandle {
self.setup_timers();
self.timers
.schedule_callback(callback, duration, self.timer_source())
}
@ -1158,6 +1243,7 @@ impl GlobalScope {
self.timers.unschedule_callback(handle);
}
/// <https://html.spec.whatwg.org/multipage/#timer-initialisation-steps>
pub fn set_timeout_or_interval(
&self,
callback: TimerCallback,
@ -1165,6 +1251,7 @@ impl GlobalScope {
timeout: i32,
is_interval: IsInterval,
) -> i32 {
self.setup_timers();
self.timers.set_timeout_or_interval(
self,
callback,
@ -1176,27 +1263,27 @@ impl GlobalScope {
}
pub fn clear_timeout_or_interval(&self, handle: i32) {
self.timers.clear_timeout_or_interval(self, handle)
self.timers.clear_timeout_or_interval(self, handle);
}
pub fn fire_timer(&self, handle: TimerEventId) {
self.timers.fire_timer(handle, self)
self.timers.fire_timer(handle, self);
}
pub fn resume(&self) {
self.timers.resume()
self.timers.resume();
}
pub fn suspend(&self) {
self.timers.suspend()
self.timers.suspend();
}
pub fn slow_down_timers(&self) {
self.timers.slow_down()
self.timers.slow_down();
}
pub fn speed_up_timers(&self) {
self.timers.speed_up()
self.timers.speed_up();
}
fn timer_source(&self) -> TimerSource {

View file

@ -28,24 +28,22 @@ use crate::script_runtime::{
};
use crate::task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue};
use crate::task_source::TaskSourceName;
use crossbeam_channel::{unbounded, Receiver, Sender};
use crossbeam_channel::{after, unbounded, Receiver, Sender};
use devtools_traits::DevtoolScriptControlMsg;
use dom_struct::dom_struct;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
use ipc_channel::ipc::{IpcReceiver, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{JSContext, JS_AddInterruptCallback};
use js::jsval::UndefinedValue;
use msg::constellation_msg::PipelineId;
use net_traits::request::{CredentialsMode, Destination, ParserMetadata, Referrer, RequestBuilder};
use net_traits::{CustomResponseMediator, IpcSend};
use script_traits::{
ScopeThings, ServiceWorkerMsg, TimerEvent, WorkerGlobalScopeInit, WorkerScriptLoadOrigin,
};
use script_traits::{ScopeThings, ServiceWorkerMsg, WorkerGlobalScopeInit, WorkerScriptLoadOrigin};
use servo_config::pref;
use servo_rand::random;
use servo_url::ServoUrl;
use std::thread;
use std::time::Duration;
use std::time::{Duration, Instant};
use style::thread_state::{self, ThreadState};
/// Messages used to control service worker event loop
@ -118,7 +116,6 @@ impl QueuedTaskConversion for ServiceWorkerScriptMsg {
pub enum MixedMessage {
FromServiceWorker(ServiceWorkerScriptMsg),
FromDevtools(DevtoolScriptControlMsg),
FromTimeoutThread(()),
}
#[derive(Clone, JSTraceable)]
@ -147,26 +144,30 @@ unsafe_no_jsmanaged_fields!(TaskQueue<ServiceWorkerScriptMsg>);
#[dom_struct]
pub struct ServiceWorkerGlobalScope {
workerglobalscope: WorkerGlobalScope,
#[ignore_malloc_size_of = "Defined in std"]
task_queue: TaskQueue<ServiceWorkerScriptMsg>,
#[ignore_malloc_size_of = "Defined in std"]
own_sender: Sender<ServiceWorkerScriptMsg>,
/// A port on which a single "time-out" message can be received,
/// indicating the sw should stop running,
/// while still draining the task-queue
// and running all enqueued, and not cancelled, tasks.
#[ignore_malloc_size_of = "Defined in std"]
timer_event_port: Receiver<()>,
time_out_port: Receiver<Instant>,
#[ignore_malloc_size_of = "Defined in std"]
swmanager_sender: IpcSender<ServiceWorkerMsg>,
scope_url: ServoUrl,
}
impl WorkerEventLoopMethods for ServiceWorkerGlobalScope {
type TimerMsg = ();
type WorkerMsg = ServiceWorkerScriptMsg;
type Event = MixedMessage;
fn timer_event_port(&self) -> &Receiver<()> {
&self.timer_event_port
}
fn task_queue(&self) -> &TaskQueue<ServiceWorkerScriptMsg> {
&self.task_queue
}
@ -183,10 +184,6 @@ impl WorkerEventLoopMethods for ServiceWorkerGlobalScope {
MixedMessage::FromServiceWorker(msg)
}
fn from_timer_msg(&self, msg: ()) -> MixedMessage {
MixedMessage::FromTimeoutThread(msg)
}
fn from_devtools_msg(&self, msg: DevtoolScriptControlMsg) -> MixedMessage {
MixedMessage::FromDevtools(msg)
}
@ -200,8 +197,7 @@ impl ServiceWorkerGlobalScope {
runtime: Runtime,
own_sender: Sender<ServiceWorkerScriptMsg>,
receiver: Receiver<ServiceWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<()>,
time_out_port: Receiver<Instant>,
swmanager_sender: IpcSender<ServiceWorkerMsg>,
scope_url: ServoUrl,
) -> ServiceWorkerGlobalScope {
@ -213,12 +209,11 @@ impl ServiceWorkerGlobalScope {
worker_url,
runtime,
from_devtools_receiver,
timer_event_chan,
None,
),
task_queue: TaskQueue::new(receiver, own_sender.clone()),
timer_event_port: timer_event_port,
own_sender: own_sender,
time_out_port,
swmanager_sender: swmanager_sender,
scope_url: scope_url,
}
@ -232,8 +227,7 @@ impl ServiceWorkerGlobalScope {
runtime: Runtime,
own_sender: Sender<ServiceWorkerScriptMsg>,
receiver: Receiver<ServiceWorkerScriptMsg>,
timer_event_chan: IpcSender<TimerEvent>,
timer_event_port: Receiver<()>,
time_out_port: Receiver<Instant>,
swmanager_sender: IpcSender<ServiceWorkerMsg>,
scope_url: ServoUrl,
) -> DomRoot<ServiceWorkerGlobalScope> {
@ -245,8 +239,7 @@ impl ServiceWorkerGlobalScope {
runtime,
own_sender,
receiver,
timer_event_chan,
timer_event_port,
time_out_port,
swmanager_sender,
scope_url,
));
@ -320,9 +313,12 @@ impl ServiceWorkerGlobalScope {
let (devtools_mpsc_chan, devtools_mpsc_port) = unbounded();
ROUTER
.route_ipc_receiver_to_crossbeam_sender(devtools_receiver, devtools_mpsc_chan);
// TODO XXXcreativcoder use this timer_ipc_port, when we have a service worker instance here
let (timer_ipc_chan, _timer_ipc_port) = ipc::channel().unwrap();
let (timer_chan, timer_port) = unbounded();
// Service workers are time limited
// https://w3c.github.io/ServiceWorker/#service-worker-lifetime
let sw_lifetime_timeout = pref!(dom.serviceworker.timeout_seconds) as u64;
let time_out_port = after(Duration::new(sw_lifetime_timeout, 0));
let global = ServiceWorkerGlobalScope::new(
init,
url,
@ -330,8 +326,7 @@ impl ServiceWorkerGlobalScope {
runtime,
own_sender,
receiver,
timer_ipc_chan,
timer_port,
time_out_port,
swmanager_sender,
scope_url,
);
@ -343,15 +338,6 @@ impl ServiceWorkerGlobalScope {
}
scope.execute_script(DOMString::from(source));
// Service workers are time limited
thread::Builder::new()
.name("SWTimeoutThread".to_owned())
.spawn(move || {
let sw_lifetime_timeout = pref!(dom.serviceworker.timeout_seconds) as u64;
thread::sleep(Duration::new(sw_lifetime_timeout, 0));
let _ = timer_chan.send(());
})
.expect("Thread spawning failed");
global.dispatch_activate();
let reporter_name = format!("service-worker-reporter-{}", random::<u64>());
@ -364,8 +350,9 @@ impl ServiceWorkerGlobalScope {
// by inside settings until it is destroyed.
// The worker processing model remains on this step
// until the event loop is destroyed,
// which happens after the closing flag is set to true.
while !scope.is_closing() {
// which happens after the closing flag is set to true,
// or until the worker has run beyond its allocated time.
while !scope.is_closing() || !global.has_timed_out() {
run_worker_event_loop(&*global, None);
}
},
@ -398,15 +385,21 @@ impl ServiceWorkerGlobalScope {
self.handle_script_event(msg);
true
},
MixedMessage::FromTimeoutThread(_) => {
let _ = self
.swmanager_sender
.send(ServiceWorkerMsg::Timeout(self.scope_url.clone()));
false
},
}
}
fn has_timed_out(&self) -> bool {
// Note: this should be included in the `select` inside `run_worker_event_loop`,
// otherwise a block on the select can prevent the timeout.
if self.time_out_port.try_recv().is_ok() {
let _ = self
.swmanager_sender
.send(ServiceWorkerMsg::Timeout(self.scope_url.clone()));
return true;
}
false
}
fn handle_script_event(&self, msg: ServiceWorkerScriptMsg) {
use self::ServiceWorkerScriptMsg::*;

View file

@ -106,8 +106,7 @@ use script_layout_interface::{PendingImageState, TrustedNodeAddress};
use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
use script_traits::{ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData};
use script_traits::{
ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEvent,
TimerEventId,
ScriptMsg, ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId,
};
use script_traits::{TimerSchedulerMsg, WindowSizeData, WindowSizeType};
use selectors::attr::CaseSensitivity;
@ -2186,7 +2185,6 @@ impl Window {
constellation_chan: ScriptToConstellationChan,
control_chan: IpcSender<ConstellationControlMsg>,
scheduler_chan: IpcSender<TimerSchedulerMsg>,
timer_event_chan: IpcSender<TimerEvent>,
layout_chan: Sender<Msg>,
pipelineid: PipelineId,
parent_info: Option<PipelineId>,
@ -2229,7 +2227,6 @@ impl Window {
constellation_chan,
scheduler_chan,
resource_threads,
timer_event_chan,
origin,
microtask_queue,
is_headless,

View file

@ -34,6 +34,7 @@ use crate::task_source::networking::NetworkingTaskSource;
use crate::task_source::performance_timeline::PerformanceTimelineTaskSource;
use crate::task_source::port_message::PortMessageQueue;
use crate::task_source::remote_event::RemoteEventTaskSource;
use crate::task_source::timer::TimerTaskSource;
use crate::task_source::websocket::WebsocketTaskSource;
use crate::timers::{IsInterval, TimerCallback};
use crossbeam_channel::Receiver;
@ -50,7 +51,6 @@ use net_traits::request::{
};
use net_traits::IpcSend;
use script_traits::WorkerGlobalScopeInit;
use script_traits::{TimerEvent, TimerEventId};
use servo_url::{MutableOrigin, ServoUrl};
use std::cell::Ref;
use std::default::Default;
@ -120,7 +120,6 @@ impl WorkerGlobalScope {
worker_url: ServoUrl,
runtime: Runtime,
from_devtools_receiver: Receiver<DevtoolScriptControlMsg>,
timer_event_chan: IpcSender<TimerEvent>,
closing: Option<Arc<AtomicBool>>,
) -> Self {
// Install a pipeline-namespace in the current thread.
@ -134,7 +133,6 @@ impl WorkerGlobalScope {
init.script_to_constellation_chan,
init.scheduler_chan,
init.resource_threads,
timer_event_chan,
MutableOrigin::new(init.origin),
runtime.microtask_queue.clone(),
init.is_headless,
@ -437,6 +435,10 @@ impl WorkerGlobalScope {
PortMessageQueue(self.script_chan(), self.pipeline_id())
}
pub fn timer_task_source(&self) -> TimerTaskSource {
TimerTaskSource(self.script_chan(), self.pipeline_id())
}
pub fn remote_event_task_source(&self) -> RemoteEventTaskSource {
RemoteEventTaskSource(self.script_chan(), self.pipeline_id())
}
@ -466,10 +468,6 @@ impl WorkerGlobalScope {
}
}
pub fn handle_fire_timer(&self, timer_id: TimerEventId) {
self.upcast::<GlobalScope>().fire_timer(timer_id);
}
pub fn close(&self) {
if let Some(ref closing) = self.closing {
closing.store(true, Ordering::SeqCst);

View file

@ -15,7 +15,6 @@ use crate::script_thread::MainThreadScriptMsg;
use crossbeam_channel::Sender;
use devtools_traits::ScriptToDevtoolsControlMsg;
use dom_struct::dom_struct;
use ipc_channel::ipc;
use ipc_channel::ipc::IpcSender;
use js::jsval::UndefinedValue;
use js::rust::Runtime;
@ -55,8 +54,6 @@ impl WorkletGlobalScope {
executor: WorkletExecutor,
init: &WorkletGlobalScopeInit,
) -> Self {
// Any timer events fired on this global are ignored.
let (timer_event_chan, _) = ipc::channel().unwrap();
let script_to_constellation_chan = ScriptToConstellationChan {
sender: init.to_constellation_sender.clone(),
pipeline_id,
@ -70,7 +67,6 @@ impl WorkletGlobalScope {
script_to_constellation_chan,
init.scheduler_chan.clone(),
init.resource_threads.clone(),
timer_event_chan,
MutableOrigin::new(ImmutableOrigin::new_opaque()),
Default::default(),
init.is_headless,