diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2019-11-26 16:26:20 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-26 16:26:20 -0500 |
commit | a922c497fade0250123b86d7535838c9a8d3b0af (patch) | |
tree | 58d60290dab73537d294c8a81dbef091279dc01a /components/script/dom/serviceworkerglobalscope.rs | |
parent | 8e0aa68aaafd96abc589f185f7f863f96c553e26 (diff) | |
parent | 50a7111eb65155fc7a0bdb1646c4a2e0ebdd8f90 (diff) | |
download | servo-a922c497fade0250123b86d7535838c9a8d3b0af.tar.gz servo-a922c497fade0250123b86d7535838c9a8d3b0af.zip |
Auto merge of #24758 - gterzian:impl_timer_task_source, r=nox
Implement timer-task-source, time-out service worker
<!-- Please describe your changes on the following line: -->
Implements the timer task-source, and folds the IPC glue-code into a single route set by the globalscope.
Also switches service worker to using a dedicated "time-out" mechanism, which previously relied on the timer mechanism(and I think didn't actually implement script timers).
---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `___` with appropriate data: -->
- [ ] `./mach build -d` does not report any errors
- [ ] `./mach test-tidy` does not report any errors
- [ ] These changes fix #24747 (GitHub issue number if applicable)
<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because ___
<!-- Also, please make sure that "Allow edits from maintainers" checkbox is checked, so that we can help you if you get stuck somewhere along the way.-->
<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->
Diffstat (limited to 'components/script/dom/serviceworkerglobalscope.rs')
-rw-r--r-- | components/script/dom/serviceworkerglobalscope.rs | 87 |
1 files changed, 40 insertions, 47 deletions
diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index cb72a4a25e4..2a3f4d7041a 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -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::*; |