Skip to content

Commit

Permalink
impl timer-task-source, dedicated time-out mechanism for service-worker
Browse files Browse the repository at this point in the history
  • Loading branch information
gterzian committed Nov 19, 2019
1 parent d553158 commit 50a7111
Show file tree
Hide file tree
Showing 13 changed files with 241 additions and 204 deletions.
21 changes: 6 additions & 15 deletions components/script/dom/abstractworkerglobalscope.rs
Expand Up @@ -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,
Expand All @@ -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()),
};
Expand All @@ -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)),
}
Expand Down
45 changes: 2 additions & 43 deletions components/script/dom/dedicatedworkerglobalscope.rs
Expand Up @@ -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};
Expand All @@ -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;
Expand Down Expand Up @@ -92,7 +92,6 @@ pub enum DedicatedWorkerScriptMsg {

pub enum MixedMessage {
FromWorker(DedicatedWorkerScriptMsg),
FromScheduler((TrustedWorkerAddress, TimerEvent)),
FromDevtools(DevtoolScriptControlMsg),
}

Expand Down Expand Up @@ -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"]
Expand All @@ -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
}
Expand All @@ -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)
}
Expand All @@ -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 {
Expand All @@ -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,
Expand All @@ -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> {
Expand All @@ -282,8 +264,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender,
own_sender,
receiver,
timer_event_chan,
timer_event_port,
closing,
image_cache,
));
Expand Down Expand Up @@ -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),
Expand All @@ -373,8 +342,6 @@ impl DedicatedWorkerGlobalScope {
parent_sender.clone(),
own_sender,
receiver,
timer_ipc_chan,
timer_rx,
closing,
image_cache,
);
Expand Down Expand Up @@ -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,
Expand Down
4 changes: 0 additions & 4 deletions components/script/dom/dissimilaroriginwindow.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -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(),
Expand All @@ -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.
Expand Down

0 comments on commit 50a7111

Please sign in to comment.