Rename Runnable to Task

The changes are:
 * `*Runnable` -> `*Task`;
 * `RunnableMsg` -> `Task`;
 * `RunnableWrapper` -> `TaskCanceller`;
 * `MainThreadRunnable` -> `MainThreadTask`;
 * `wrap_runnable` -> `wrap_task`;
 * `get_runnable_wrapper` -> `task_canceller`;
 * `handler` -> `run`;
 * `main_thread_handler` -> `run_with_script_thread`.
This commit is contained in:
Anthony Ramine 2017-09-16 02:09:26 +02:00
parent 52a6f63608
commit 56117d3185
38 changed files with 370 additions and 332 deletions

View file

@ -32,8 +32,7 @@ use dom::promise::Promise;
use js::jsapi::JSAutoCompartment;
use js::jsapi::JSTracer;
use libc;
use script_thread::Runnable;
use script_thread::ScriptThread;
use script_thread::{ScriptThread, Task};
use std::cell::RefCell;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::hash_map::HashMap;
@ -121,12 +120,12 @@ impl TrustedPromise {
})
}
/// A runnable which will reject the promise.
/// A task which will reject the promise.
#[allow(unrooted_must_root)]
pub fn reject_runnable(self, error: Error) -> impl Runnable + Send {
pub fn reject_task(self, error: Error) -> impl Send + Task {
struct RejectPromise(TrustedPromise, Error);
impl Runnable for RejectPromise {
fn main_thread_handler(self: Box<Self>, script_thread: &ScriptThread) {
impl Task for RejectPromise {
fn run_with_script_thread(self: Box<Self>, script_thread: &ScriptThread) {
debug!("Rejecting promise.");
let this = *self;
let cx = script_thread.get_cx();
@ -138,14 +137,15 @@ impl TrustedPromise {
RejectPromise(self, error)
}
/// A runnable which will resolve the promise.
/// A task which will resolve the promise.
#[allow(unrooted_must_root)]
pub fn resolve_runnable<T>(self, value: T) -> impl Runnable + Send where
T: ToJSValConvertible + Send
pub fn resolve_task<T>(self, value: T) -> impl Send + Task
where
T: ToJSValConvertible + Send,
{
struct ResolvePromise<T>(TrustedPromise, T);
impl<T: ToJSValConvertible> Runnable for ResolvePromise<T> {
fn main_thread_handler(self: Box<Self>, script_thread: &ScriptThread) {
impl<T: ToJSValConvertible> Task for ResolvePromise<T> {
fn run_with_script_thread(self: Box<Self>, script_thread: &ScriptThread) {
debug!("Resolving promise.");
let this = *self;
let cx = script_thread.get_cx();

View file

@ -35,7 +35,7 @@ use ipc_channel::router::ROUTER;
use js::conversions::ConversionResult;
use js::jsapi::{JSAutoCompartment, JSContext, JSObject};
use js::jsval::{ObjectValue, UndefinedValue};
use script_thread::Runnable;
use script_thread::Task;
use std::cell::Ref;
use std::collections::HashMap;
use std::rc::Rc;
@ -224,25 +224,28 @@ pub fn response_async<T: AsyncBluetoothListener + DomObject + 'static>(
receiver: Trusted::new(receiver),
}));
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
struct ListenerRunnable<T: AsyncBluetoothListener + DomObject> {
struct ListenerTask<T: AsyncBluetoothListener + DomObject> {
context: Arc<Mutex<BluetoothContext<T>>>,
action: BluetoothResponseResult,
}
impl<T: AsyncBluetoothListener + DomObject> Runnable for ListenerRunnable<T> {
fn handler(self: Box<Self>) {
impl<T> Task for ListenerTask<T>
where
T: AsyncBluetoothListener + DomObject,
{
fn run(self: Box<Self>) {
let this = *self;
let mut context = this.context.lock().unwrap();
context.response(this.action);
}
}
let runnable = box ListenerRunnable {
let task = box ListenerTask {
context: context.clone(),
action: message.to().unwrap(),
};
let result = task_source.queue_wrapperless(runnable);
let result = task_source.queue_unconditionally(task);
if let Err(err) = result {
warn!("failed to deliver network data: {:?}", err);
}

View file

@ -190,7 +190,7 @@ impl DedicatedWorkerGlobalScope {
&init.resource_threads.sender()) {
Err(_) => {
println!("error loading script {}", serialized_worker_url);
parent_sender.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
parent_sender.send(CommonScriptMsg::Task(WorkerEvent,
box SimpleWorkerErrorHandler::new(worker))).unwrap();
return;
}
@ -352,7 +352,7 @@ impl DedicatedWorkerGlobalScope {
let worker = self.worker.borrow().as_ref().unwrap().clone();
// TODO: Should use the DOM manipulation task source.
self.parent_sender
.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
.send(CommonScriptMsg::Task(WorkerEvent,
box WorkerErrorHandler::new(worker, error_info)))
.unwrap();
}
@ -376,7 +376,7 @@ impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope {
let data = StructuredCloneData::write(cx, message)?;
let worker = self.worker.borrow().as_ref().unwrap().clone();
self.parent_sender
.send(CommonScriptMsg::RunnableMsg(WorkerEvent,
.send(CommonScriptMsg::Task(WorkerEvent,
box WorkerMessageHandler::new(worker, data)))
.unwrap();
Ok(())

View file

@ -113,7 +113,7 @@ use net_traits::response::HttpsState;
use num_traits::ToPrimitive;
use script_layout_interface::message::{Msg, ReflowQueryType};
use script_runtime::{CommonScriptMsg, ScriptThreadEventCategory};
use script_thread::{MainThreadScriptMsg, Runnable, ScriptThread};
use script_thread::{MainThreadScriptMsg, ScriptThread, Task};
use script_traits::{AnimationState, CompositorEvent, DocumentActivity};
use script_traits::{MouseButton, MouseEventType, MozBrowserEvent};
use script_traits::{MsDuration, ScriptMsg, TouchpadPressurePhase};
@ -2609,7 +2609,7 @@ impl Document {
let trusted_pending = Trusted::new(pending);
let trusted_promise = TrustedPromise::new(promise.clone());
let handler = ElementPerformFullscreenEnter::new(trusted_pending, trusted_promise, error);
let script_msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::EnterFullscreen, handler);
let script_msg = CommonScriptMsg::Task(ScriptThreadEventCategory::EnterFullscreen, handler);
let msg = MainThreadScriptMsg::Common(script_msg);
window.main_thread_script_chan().send(msg).unwrap();
@ -2641,7 +2641,7 @@ impl Document {
let trusted_element = Trusted::new(element.r());
let trusted_promise = TrustedPromise::new(promise.clone());
let handler = ElementPerformFullscreenExit::new(trusted_element, trusted_promise);
let script_msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::ExitFullscreen, handler);
let script_msg = CommonScriptMsg::Task(ScriptThreadEventCategory::ExitFullscreen, handler);
let msg = MainThreadScriptMsg::Common(script_msg);
window.main_thread_script_chan().send(msg).unwrap();
@ -4016,8 +4016,8 @@ impl DocumentProgressHandler {
}
}
impl Runnable for DocumentProgressHandler {
fn handler(self: Box<DocumentProgressHandler>) {
impl Task for DocumentProgressHandler {
fn run(self: Box<Self>) {
let document = self.addr.root();
let window = document.window();
if window.is_alive() {

View file

@ -87,7 +87,7 @@ use js::jsval::JSVal;
use net_traits::request::CorsSettings;
use ref_filter_map::ref_filter_map;
use script_layout_interface::message::ReflowQueryType;
use script_thread::{Runnable, ScriptThread};
use script_thread::{ScriptThread, Task};
use selectors::attr::{AttrSelectorOperation, NamespaceConstraint, CaseSensitivity};
use selectors::matching::{ElementSelectorFlags, LocalMatchingContext, MatchingContext, MatchingMode};
use selectors::matching::{HAS_EDGE_CHILD_SELECTOR, HAS_SLOW_SELECTOR, HAS_SLOW_SELECTOR_LATER_SIBLINGS};
@ -3044,9 +3044,9 @@ impl ElementPerformFullscreenEnter {
}
}
impl Runnable for ElementPerformFullscreenEnter {
impl Task for ElementPerformFullscreenEnter {
#[allow(unrooted_must_root)]
fn handler(self: Box<ElementPerformFullscreenEnter>) {
fn run(self: Box<Self>) {
let element = self.element.root();
let document = document_from_node(element.r());
@ -3097,9 +3097,9 @@ impl ElementPerformFullscreenExit {
}
}
impl Runnable for ElementPerformFullscreenExit {
impl Task for ElementPerformFullscreenExit {
#[allow(unrooted_must_root)]
fn handler(self: Box<ElementPerformFullscreenExit>) {
fn run(self: Box<Self>) {
let element = self.element.root();
let document = document_from_node(element.r());
// TODO Step 9.1-5

View file

@ -20,7 +20,7 @@ use dom::node::Node;
use dom::virtualmethods::vtable_for;
use dom::window::Window;
use dom_struct::dom_struct;
use script_thread::Runnable;
use script_thread::Task;
use servo_atoms::Atom;
use std::cell::Cell;
use std::default::Default;
@ -381,15 +381,15 @@ pub enum EventStatus {
}
// https://dom.spec.whatwg.org/#concept-event-fire
pub struct EventRunnable {
pub struct EventTask {
pub target: Trusted<EventTarget>,
pub name: Atom,
pub bubbles: EventBubbles,
pub cancelable: EventCancelable,
}
impl Runnable for EventRunnable {
fn handler(self: Box<EventRunnable>) {
impl Task for EventTask {
fn run(self: Box<Self>) {
let target = self.target.root();
let bubbles = self.bubbles;
let cancelable = self.cancelable;
@ -398,13 +398,13 @@ impl Runnable for EventRunnable {
}
// https://html.spec.whatwg.org/multipage/#fire-a-simple-event
pub struct SimpleEventRunnable {
pub struct SimpleEventTask {
pub target: Trusted<EventTarget>,
pub name: Atom,
}
impl Runnable for SimpleEventRunnable {
fn handler(self: Box<SimpleEventRunnable>) {
impl Task for SimpleEventTask {
fn run(self: Box<Self>) {
let target = self.target.root();
target.fire_event(self.name);
}

View file

@ -27,7 +27,7 @@ use net_traits::{CoreResourceMsg, FetchMetadata, FetchResponseMsg, FetchResponse
use net_traits::request::{CacheMode, CorsSettings, CredentialsMode};
use net_traits::request::{RequestInit, RequestMode};
use network_listener::{NetworkListener, PreInvoke};
use script_thread::Runnable;
use script_thread::Task;
use servo_atoms::Atom;
use servo_url::ServoUrl;
use std::cell::Cell;
@ -96,10 +96,10 @@ impl EventSourceContext {
if self.gen_id != event_source.generation_id.get() {
return;
}
let runnable = box AnnounceConnectionRunnable {
let task = box AnnounceConnectionTask {
event_source: self.event_source.clone()
};
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
let _ = event_source.global().networking_task_source().queue(task, &*event_source.global());
}
fn fail_the_connection(&self) {
@ -107,10 +107,10 @@ impl EventSourceContext {
if self.gen_id != event_source.generation_id.get() {
return;
}
let runnable = box FailConnectionRunnable {
let task = box FailConnectionTask {
event_source: self.event_source.clone()
};
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
let _ = event_source.global().networking_task_source().queue(task, &*event_source.global());
}
// https://html.spec.whatwg.org/multipage/#reestablish-the-connection
@ -122,11 +122,11 @@ impl EventSourceContext {
}
// Step 1
let runnable = box ReestablishConnectionRunnable {
let task = box ReestablishConnectionTask {
event_source: self.event_source.clone(),
action_sender: self.action_sender.clone()
};
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
let _ = event_source.global().networking_task_source().queue(task, &*event_source.global());
}
// https://html.spec.whatwg.org/multipage/#processField
@ -186,11 +186,11 @@ impl EventSourceContext {
self.event_type.clear();
self.data.clear();
// Step 8
let runnable = box DispatchEventRunnable {
let task = box DispatchEventTask {
event_source: self.event_source.clone(),
event: Trusted::new(&event)
};
let _ = event_source.global().networking_task_source().queue(runnable, &*event_source.global());
let _ = event_source.global().networking_task_source().queue(task, &*event_source.global());
}
// https://html.spec.whatwg.org/multipage/#event-stream-interpretation
@ -425,7 +425,7 @@ impl EventSource {
let listener = NetworkListener {
context: Arc::new(Mutex::new(context)),
task_source: global.networking_task_source(),
wrapper: Some(global.get_runnable_wrapper())
canceller: Some(global.task_canceller())
};
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
listener.notify_fetch(message.to().unwrap());
@ -469,13 +469,13 @@ impl EventSourceMethods for EventSource {
}
}
pub struct AnnounceConnectionRunnable {
pub struct AnnounceConnectionTask {
event_source: Trusted<EventSource>,
}
impl Runnable for AnnounceConnectionRunnable {
impl Task for AnnounceConnectionTask {
// https://html.spec.whatwg.org/multipage/#announce-the-connection
fn handler(self: Box<AnnounceConnectionRunnable>) {
fn run(self: Box<Self>) {
let event_source = self.event_source.root();
if event_source.ready_state.get() != ReadyState::Closed {
event_source.ready_state.set(ReadyState::Open);
@ -484,13 +484,13 @@ impl Runnable for AnnounceConnectionRunnable {
}
}
pub struct FailConnectionRunnable {
pub struct FailConnectionTask {
event_source: Trusted<EventSource>,
}
impl Runnable for FailConnectionRunnable {
impl Task for FailConnectionTask {
// https://html.spec.whatwg.org/multipage/#fail-the-connection
fn handler(self: Box<FailConnectionRunnable>) {
fn run(self: Box<Self>) {
let event_source = self.event_source.root();
if event_source.ready_state.get() != ReadyState::Closed {
event_source.ready_state.set(ReadyState::Closed);
@ -499,14 +499,14 @@ impl Runnable for FailConnectionRunnable {
}
}
pub struct ReestablishConnectionRunnable {
pub struct ReestablishConnectionTask {
event_source: Trusted<EventSource>,
action_sender: ipc::IpcSender<FetchResponseMsg>,
}
impl Runnable for ReestablishConnectionRunnable {
impl Task for ReestablishConnectionTask {
// https://html.spec.whatwg.org/multipage/#reestablish-the-connection
fn handler(self: Box<ReestablishConnectionRunnable>) {
fn run(self: Box<Self>) {
let event_source = self.event_source.root();
// Step 1.1
if event_source.ready_state.get() == ReadyState::Closed {
@ -556,14 +556,14 @@ impl EventSourceTimeoutCallback {
}
}
pub struct DispatchEventRunnable {
pub struct DispatchEventTask {
event_source: Trusted<EventSource>,
event: Trusted<MessageEvent>,
}
impl Runnable for DispatchEventRunnable {
impl Task for DispatchEventTask {
// https://html.spec.whatwg.org/multipage/#dispatchMessage
fn handler(self: Box<DispatchEventRunnable>) {
fn run(self: Box<Self>) {
let event_source = self.event_source.root();
// Step 8
if event_source.ready_state.get() != ReadyState::Closed {

View file

@ -29,7 +29,7 @@ use js::jsapi::JSAutoCompartment;
use js::jsapi::JSContext;
use js::jsval::{self, JSVal};
use js::typedarray::{ArrayBuffer, CreateWith};
use script_thread::RunnableWrapper;
use script_thread::TaskCanceller;
use servo_atoms::Atom;
use std::cell::Cell;
use std::ptr;
@ -383,11 +383,18 @@ impl FileReader {
let gen_id = self.generation_id.get();
let global = self.global();
let wrapper = global.get_runnable_wrapper();
let canceller = global.task_canceller();
let task_source = global.file_reading_task_source();
thread::Builder::new().name("file reader async operation".to_owned()).spawn(move || {
perform_annotated_read_operation(gen_id, load_data, blob_contents, fr, task_source, wrapper)
perform_annotated_read_operation(
gen_id,
load_data,
blob_contents,
fr,
task_source,
canceller,
)
}).expect("Thread spawning failed");
Ok(())
@ -399,19 +406,21 @@ impl FileReader {
}
// https://w3c.github.io/FileAPI/#thread-read-operation
fn perform_annotated_read_operation(gen_id: GenerationId,
data: ReadMetaData,
blob_contents: Arc<Vec<u8>>,
filereader: TrustedFileReader,
task_source: FileReadingTaskSource,
wrapper: RunnableWrapper) {
fn perform_annotated_read_operation(
gen_id: GenerationId,
data: ReadMetaData,
blob_contents: Arc<Vec<u8>>,
filereader: TrustedFileReader,
task_source: FileReadingTaskSource,
canceller: TaskCanceller,
) {
// Step 4
let task = FileReadingRunnable::new(FileReadingTask::ProcessRead(filereader.clone(), gen_id));
task_source.queue_with_wrapper(task, &wrapper).unwrap();
task_source.queue_with_canceller(task, &canceller).unwrap();
let task = FileReadingRunnable::new(FileReadingTask::ProcessReadData(filereader.clone(), gen_id));
task_source.queue_with_wrapper(task, &wrapper).unwrap();
task_source.queue_with_canceller(task, &canceller).unwrap();
let task = FileReadingRunnable::new(FileReadingTask::ProcessReadEOF(filereader, gen_id, data, blob_contents));
task_source.queue_with_wrapper(task, &wrapper).unwrap();
task_source.queue_with_canceller(task, &canceller).unwrap();
}

View file

@ -38,7 +38,7 @@ use msg::constellation_msg::PipelineId;
use net_traits::{CoreResourceThread, ResourceThreads, IpcSend};
use profile_traits::{mem, time};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort};
use script_thread::{MainThreadScriptChan, RunnableWrapper, ScriptThread};
use script_thread::{MainThreadScriptChan, ScriptThread, TaskCanceller};
use script_traits::{MsDuration, ScriptToConstellationChan, TimerEvent};
use script_traits::{TimerEventId, TimerSchedulerMsg, TimerSource};
use servo_url::{MutableOrigin, ServoUrl};
@ -477,14 +477,14 @@ impl GlobalScope {
unreachable!();
}
/// Returns a wrapper for runnables to ensure they are cancelled if
/// the global scope is being destroyed.
pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
/// Returns the task canceller of this global to ensure that everything is
/// properly cancelled when the global scope is destroyed.
pub fn task_canceller(&self) -> TaskCanceller {
if let Some(window) = self.downcast::<Window>() {
return window.get_runnable_wrapper();
return window.task_canceller();
}
if let Some(worker) = self.downcast::<WorkerGlobalScope>() {
return worker.get_runnable_wrapper();
return worker.task_canceller();
}
unreachable!();
}

View file

@ -16,7 +16,7 @@ use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix};
use script_thread::Runnable;
use script_thread::Task;
use std::cell::Cell;
use task_source::TaskSource;
@ -74,22 +74,22 @@ impl VirtualMethods for HTMLDetailsElement {
let window = window_from_node(self);
let task_source = window.dom_manipulation_task_source();
let details = Trusted::new(self);
let runnable = box DetailsNotificationRunnable {
let task = box DetailsNotificationTask {
element: details,
toggle_number: counter
};
let _ = task_source.queue(runnable, window.upcast());
let _ = task_source.queue(task, window.upcast());
}
}
}
pub struct DetailsNotificationRunnable {
pub struct DetailsNotificationTask {
element: Trusted<HTMLDetailsElement>,
toggle_number: u32
}
impl Runnable for DetailsNotificationRunnable {
fn handler(self: Box<DetailsNotificationRunnable>) {
impl Task for DetailsNotificationTask {
fn run(self: Box<Self>) {
let target = self.element.root();
if target.check_toggle_count(self.toggle_number) {
target.upcast::<EventTarget>().fire_event(atom!("toggle"));

View file

@ -49,7 +49,7 @@ use html5ever::{LocalName, Prefix};
use hyper::header::{Charset, ContentDisposition, ContentType, DispositionParam, DispositionType};
use hyper::method::Method;
use msg::constellation_msg::PipelineId;
use script_thread::{MainThreadScriptMsg, Runnable};
use script_thread::{MainThreadScriptMsg, Task};
use script_traits::LoadData;
use servo_rand::random;
use std::borrow::ToOwned;
@ -432,8 +432,8 @@ impl HTMLFormElement {
let window = window_from_node(self);
// Step 1
// Each planned navigation runnable is tagged with a generation ID, and
// before the runnable is handled, it first checks whether the HTMLFormElement's
// Each planned navigation task is tagged with a generation ID, and
// before the task is handled, it first checks whether the HTMLFormElement's
// generation ID is the same as its own generation ID.
let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1));
@ -1115,8 +1115,8 @@ struct PlannedNavigation {
form: Trusted<HTMLFormElement>
}
impl Runnable for PlannedNavigation {
fn handler(self: Box<PlannedNavigation>) {
impl Task for PlannedNavigation {
fn run(self: Box<Self>) {
if self.generation_id == self.form.root().generation_id.get() {
let script_chan = self.script_chan.clone();
script_chan.send(MainThreadScriptMsg::Navigate(self.pipeline_id, self.load_data, false)).unwrap();

View file

@ -43,7 +43,7 @@ use js::jsval::{NullValue, UndefinedValue};
use msg::constellation_msg::{FrameType, BrowsingContextId, PipelineId, TopLevelBrowsingContextId, TraversalDirection};
use net_traits::response::HttpsState;
use script_layout_interface::message::ReflowQueryType;
use script_thread::{ScriptThread, Runnable};
use script_thread::{ScriptThread, Task};
use script_traits::{IFrameLoadInfo, IFrameLoadInfoWithData, JsEvalResult, LoadData, UpdatePipelineIdReason};
use script_traits::{MozBrowserEvent, NewLayoutInfo, ScriptMsg};
use script_traits::IFrameSandboxState::{IFrameSandboxed, IFrameUnsandboxed};
@ -849,8 +849,8 @@ impl IFrameLoadEventSteps {
}
}
impl Runnable for IFrameLoadEventSteps {
fn handler(self: Box<IFrameLoadEventSteps>) {
impl Task for IFrameLoadEventSteps {
fn run(self: Box<Self>) {
let this = self.frame_element.root();
this.iframe_load_event_steps(self.pipeline_id);
}

View file

@ -48,7 +48,7 @@ use net_traits::image_cache::UsePlaceholder;
use net_traits::request::{RequestInit, Type as RequestType};
use network_listener::{NetworkListener, PreInvoke};
use num_traits::ToPrimitive;
use script_thread::{Runnable, ScriptThread};
use script_thread::{ScriptThread, Task};
use servo_url::ServoUrl;
use servo_url::origin::ImmutableOrigin;
use std::cell::{Cell, RefMut};
@ -99,16 +99,16 @@ impl HTMLImageElement {
}
}
struct ImageResponseHandlerRunnable {
struct ImageResponseHandlerTask {
element: Trusted<HTMLImageElement>,
image: ImageResponse,
generation: u32,
}
impl ImageResponseHandlerRunnable {
impl ImageResponseHandlerTask {
fn new(element: Trusted<HTMLImageElement>, image: ImageResponse, generation: u32)
-> ImageResponseHandlerRunnable {
ImageResponseHandlerRunnable {
-> ImageResponseHandlerTask {
ImageResponseHandlerTask {
element: element,
image: image,
generation: generation,
@ -116,8 +116,8 @@ impl ImageResponseHandlerRunnable {
}
}
impl Runnable for ImageResponseHandlerRunnable {
fn handler(self: Box<Self>) {
impl Task for ImageResponseHandlerTask {
fn run(self: Box<Self>) {
let element = self.element.root();
// Ignore any image response for a previous request that has been discarded.
if element.generation.get() == self.generation {
@ -191,15 +191,18 @@ impl HTMLImageElement {
let window = window_from_node(elem);
let task_source = window.networking_task_source();
let wrapper = window.get_runnable_wrapper();
let wrapper = window.task_canceller();
let generation = elem.generation.get();
ROUTER.add_route(responder_receiver.to_opaque(), box move |message| {
debug!("Got image {:?}", message);
// Return the image via a message to the script thread, which marks
// the element as dirty and triggers a reflow.
let runnable = ImageResponseHandlerRunnable::new(
trusted_node.clone(), message.to().unwrap(), generation);
let _ = task_source.queue_with_wrapper(box runnable, &wrapper);
let task = ImageResponseHandlerTask::new(
trusted_node.clone(),
message.to().unwrap(),
generation,
);
let _ = task_source.queue_with_canceller(box task, &wrapper);
});
image_cache.add_listener(id, ImageResponder::new(responder_sender, id));
@ -249,7 +252,7 @@ impl HTMLImageElement {
let listener = NetworkListener {
context: context,
task_source: window.networking_task_source(),
wrapper: Some(window.get_runnable_wrapper()),
canceller: Some(window.task_canceller()),
};
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
listener.notify_fetch(message.to().unwrap());
@ -354,12 +357,12 @@ impl HTMLImageElement {
/// Step 11.4 of https://html.spec.whatwg.org/multipage/#update-the-image-data
fn set_current_request_url_to_selected_fire_error_and_loadend(&self, src: DOMString) {
struct Task {
struct SetCurrentRequestUrlTask {
img: Trusted<HTMLImageElement>,
src: String,
}
impl Runnable for Task {
fn handler(self: Box<Self>) {
impl Task for SetCurrentRequestUrlTask {
fn run(self: Box<Self>) {
let img = self.img.root();
{
let mut current_request = img.current_request.borrow_mut();
@ -372,7 +375,7 @@ impl HTMLImageElement {
}
}
let task = box Task {
let task = box SetCurrentRequestUrlTask {
img: Trusted::new(self),
src: src.into()
};
@ -387,21 +390,21 @@ impl HTMLImageElement {
struct FireprogressEventTask {
img: Trusted<HTMLImageElement>,
}
impl Runnable for FireprogressEventTask {
fn handler(self: Box<Self>) {
impl Task for FireprogressEventTask {
fn run(self: Box<Self>) {
let progressevent = ProgressEvent::new(&self.img.root().global(),
atom!("loadstart"), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable,
false, 0, 0);
progressevent.upcast::<Event>().fire(self.img.root().upcast());
}
}
let runnable = box FireprogressEventTask {
let task = box FireprogressEventTask {
img: Trusted::new(self),
};
let document = document_from_node(self);
let window = document.window();
let task = window.dom_manipulation_task_source();
let _ = task.queue(runnable, window.upcast());
let task_source = window.dom_manipulation_task_source();
let _ = task_source.queue(task, window.upcast());
}
/// https://html.spec.whatwg.org/multipage/#update-the-source-set
@ -426,8 +429,8 @@ impl HTMLImageElement {
struct SetUrlToNoneTask {
img: Trusted<HTMLImageElement>,
}
impl Runnable for SetUrlToNoneTask {
fn handler(self: Box<Self>) {
impl Task for SetUrlToNoneTask {
fn run(self: Box<Self>) {
let img = self.img.root();
{
let mut current_request = img.current_request.borrow_mut();
@ -459,8 +462,8 @@ impl HTMLImageElement {
src: String,
url: ServoUrl
}
impl Runnable for SetUrlToStringTask {
fn handler(self: Box<Self>) {
impl Task for SetUrlToStringTask {
fn run(self: Box<Self>) {
let img = self.img.root();
{
let mut current_request = img.current_request.borrow_mut();
@ -471,15 +474,15 @@ impl HTMLImageElement {
img.upcast::<EventTarget>().fire_event(atom!("load"));
}
}
let runnable = box SetUrlToStringTask {
let task = box SetUrlToStringTask {
img: Trusted::new(self),
src: src.into(),
url: url
};
let document = document_from_node(self);
let window = document.window();
let task = window.dom_manipulation_task_source();
let _ = task.queue(runnable, window.upcast());
let task_source = window.dom_manipulation_task_source();
let _ = task_source.queue(task, window.upcast());
}
fn init_image_request(&self,

View file

@ -35,7 +35,7 @@ use microtask::{Microtask, MicrotaskRunnable};
use net_traits::{FetchResponseListener, FetchMetadata, Metadata, NetworkError};
use net_traits::request::{CredentialsMode, Destination, RequestInit, Type as RequestType};
use network_listener::{NetworkListener, PreInvoke};
use script_thread::{Runnable, ScriptThread};
use script_thread::{ScriptThread, Task};
use servo_url::ServoUrl;
use std::cell::Cell;
use std::sync::{Arc, Mutex};
@ -145,8 +145,8 @@ impl HTMLMediaElement {
window.upcast(),
);
struct InternalPauseStepsTask(Trusted<EventTarget>);
impl Runnable for InternalPauseStepsTask {
fn handler(self: Box<Self>) {
impl Task for InternalPauseStepsTask {
fn run(self: Box<Self>) {
let target = self.0.root();
// Step 2.3.1.
@ -180,8 +180,8 @@ impl HTMLMediaElement {
window.upcast(),
);
struct NotifyAboutPlayingTask(Trusted<EventTarget>);
impl Runnable for NotifyAboutPlayingTask {
fn handler(self: Box<Self>) {
impl Task for NotifyAboutPlayingTask {
fn run(self: Box<Self>) {
let target = self.0.root();
// Step 2.1.
@ -428,7 +428,7 @@ impl HTMLMediaElement {
let listener = NetworkListener {
context: context,
task_source: window.networking_task_source(),
wrapper: Some(window.get_runnable_wrapper())
canceller: Some(window.task_canceller())
};
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
@ -750,8 +750,8 @@ impl DedicatedMediaSourceFailureTask {
}
}
impl Runnable for DedicatedMediaSourceFailureTask {
fn handler(self: Box<DedicatedMediaSourceFailureTask>) {
impl Task for DedicatedMediaSourceFailureTask {
fn run(self: Box<Self>) {
self.elem.root().dedicated_media_source_failure();
}
}

View file

@ -277,7 +277,7 @@ fn fetch_a_classic_script(script: &HTMLScriptElement,
let listener = NetworkListener {
context: context,
task_source: doc.window().networking_task_source(),
wrapper: Some(doc.window().get_runnable_wrapper())
canceller: Some(doc.window().task_canceller())
};
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {

View file

@ -16,7 +16,7 @@ use dom::eventtarget::EventTarget;
use dom::globalscope::GlobalScope;
use dom_struct::dom_struct;
use js::jsapi::{HandleValue, JSContext};
use script_thread::Runnable;
use script_thread::Task;
use script_traits::{ScriptMsg, DOMMessage};
use servo_url::ServoUrl;
use std::cell::Cell;
@ -104,9 +104,9 @@ impl ServiceWorkerMethods for ServiceWorker {
event_handler!(statechange, GetOnstatechange, SetOnstatechange);
}
impl Runnable for SimpleWorkerErrorHandler<ServiceWorker> {
impl Task for SimpleWorkerErrorHandler<ServiceWorker> {
#[allow(unrooted_must_root)]
fn handler(self: Box<SimpleWorkerErrorHandler<ServiceWorker>>) {
fn run(self: Box<Self>) {
let this = *self;
ServiceWorker::dispatch_simple_error(this.addr);
}

View file

@ -17,7 +17,7 @@ use dom_struct::dom_struct;
use ipc_channel::ipc::{self, IpcSender};
use net_traits::IpcSend;
use net_traits::storage_thread::{StorageThreadMsg, StorageType};
use script_thread::Runnable;
use script_thread::Task;
use script_traits::ScriptMsg;
use servo_url::ServoUrl;
use task_source::TaskSource;
@ -167,7 +167,7 @@ impl Storage {
) {
let global = self.global();
global.as_window().dom_manipulation_task_source().queue(
box StorageEventRunnable {
box StorageEventTask {
element: Trusted::new(self),
url,
key,
@ -176,15 +176,15 @@ impl Storage {
},
global.upcast(),
).unwrap();
struct StorageEventRunnable {
struct StorageEventTask {
element: Trusted<Storage>,
url: ServoUrl,
key: Option<String>,
old_value: Option<String>,
new_value: Option<String>
}
impl Runnable for StorageEventRunnable {
fn handler(self: Box<Self>) {
impl Task for StorageEventTask {
fn run(self: Box<Self>) {
let this = *self;
let storage = this.element.root();
let global = storage.global();

View file

@ -36,7 +36,7 @@ use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::JSContext;
use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory::WebVREvent;
use script_thread::Runnable;
use script_thread::Task;
use std::cell::Cell;
use std::mem;
use std::rc::Rc;
@ -515,7 +515,7 @@ impl VRDisplay {
address: address.clone(),
sender: raf_sender.clone()
};
js_sender.send(CommonScriptMsg::RunnableMsg(WebVREvent, msg)).unwrap();
js_sender.send(CommonScriptMsg::Task(WebVREvent, msg)).unwrap();
// Run Sync Poses in parallell on Render thread
let msg = WebVRCommand::SyncPoses(display_id, near, far, sync_sender.clone());
@ -613,8 +613,8 @@ struct NotifyDisplayRAF {
sender: mpsc::Sender<Result<(f64, f64), ()>>
}
impl Runnable for NotifyDisplayRAF {
fn handler(self: Box<Self>) {
impl Task for NotifyDisplayRAF {
fn run(self: Box<Self>) {
let display = self.address.root();
display.handle_raf(&self.sender);
}

View file

@ -31,7 +31,7 @@ use net_traits::CoreResourceMsg::WebsocketConnect;
use net_traits::MessageData;
use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory::WebSocketEvent;
use script_thread::{Runnable, RunnableWrapper};
use script_thread::{Task, TaskCanceller};
use servo_url::ServoUrl;
use std::ascii::AsciiExt;
use std::borrow::ToOwned;
@ -67,30 +67,34 @@ mod close_code {
pub const TLS_FAILED: u16 = 1015;
}
pub fn close_the_websocket_connection(address: Trusted<WebSocket>,
task_source: &NetworkingTaskSource,
wrapper: &RunnableWrapper,
code: Option<u16>,
reason: String) {
pub fn close_the_websocket_connection(
address: Trusted<WebSocket>,
task_source: &NetworkingTaskSource,
canceller: &TaskCanceller,
code: Option<u16>,
reason: String,
) {
let close_task = box CloseTask {
address: address,
failed: false,
code: code,
reason: Some(reason),
};
task_source.queue_with_wrapper(close_task, &wrapper).unwrap();
task_source.queue_with_canceller(close_task, &canceller).unwrap();
}
pub fn fail_the_websocket_connection(address: Trusted<WebSocket>,
task_source: &NetworkingTaskSource,
wrapper: &RunnableWrapper) {
pub fn fail_the_websocket_connection(
address: Trusted<WebSocket>,
task_source: &NetworkingTaskSource,
canceller: &TaskCanceller,
) {
let close_task = box CloseTask {
address: address,
failed: true,
code: Some(close_code::ABNORMAL),
reason: None,
};
task_source.queue_with_wrapper(close_task, &wrapper).unwrap();
task_source.queue_with_canceller(close_task, &canceller).unwrap();
}
#[dom_struct]
@ -197,7 +201,7 @@ impl WebSocket {
*ws.sender.borrow_mut() = Some(dom_action_sender);
let task_source = global.networking_task_source();
let wrapper = global.get_runnable_wrapper();
let canceller = global.task_canceller();
thread::spawn(move || {
while let Ok(event) = dom_event_receiver.recv() {
match event {
@ -206,22 +210,22 @@ impl WebSocket {
address: address.clone(),
protocol_in_use,
};
task_source.queue_with_wrapper(open_thread, &wrapper).unwrap();
task_source.queue_with_canceller(open_thread, &canceller).unwrap();
},
WebSocketNetworkEvent::MessageReceived(message) => {
let message_thread = box MessageReceivedTask {
address: address.clone(),
message: message,
};
task_source.queue_with_wrapper(message_thread, &wrapper).unwrap();
task_source.queue_with_canceller(message_thread, &canceller).unwrap();
},
WebSocketNetworkEvent::Fail => {
fail_the_websocket_connection(address.clone(),
&task_source, &wrapper);
&task_source, &canceller);
},
WebSocketNetworkEvent::Close(code, reason) => {
close_the_websocket_connection(address.clone(),
&task_source, &wrapper, code, reason);
&task_source, &canceller, code, reason);
},
}
}
@ -261,7 +265,7 @@ impl WebSocket {
self.global()
.script_chan()
.send(CommonScriptMsg::RunnableMsg(WebSocketEvent, task))
.send(CommonScriptMsg::Task(WebSocketEvent, task))
.unwrap();
}
@ -368,7 +372,7 @@ impl WebSocketMethods for WebSocket {
let address = Trusted::new(self);
let task_source = self.global().networking_task_source();
fail_the_websocket_connection(address, &task_source, &self.global().get_runnable_wrapper());
fail_the_websocket_connection(address, &task_source, &self.global().task_canceller());
}
WebSocketRequestState::Open => {
self.ready_state.set(WebSocketRequestState::Closing);
@ -393,9 +397,9 @@ struct ConnectionEstablishedTask {
protocol_in_use: Option<String>,
}
impl Runnable for ConnectionEstablishedTask {
impl Task for ConnectionEstablishedTask {
/// https://html.spec.whatwg.org/multipage/#feedback-from-the-protocol:concept-websocket-established
fn handler(self: Box<Self>) {
fn run(self: Box<Self>) {
let ws = self.address.root();
// Step 1.
@ -418,13 +422,13 @@ struct BufferedAmountTask {
address: Trusted<WebSocket>,
}
impl Runnable for BufferedAmountTask {
impl Task for BufferedAmountTask {
// See https://html.spec.whatwg.org/multipage/#dom-websocket-bufferedamount
//
// To be compliant with standards, we need to reset bufferedAmount only when the event loop
// reaches step 1. In our implementation, the bytes will already have been sent on a background
// thread.
fn handler(self: Box<Self>) {
fn run(self: Box<Self>) {
let ws = self.address.root();
ws.buffered_amount.set(0);
@ -439,8 +443,8 @@ struct CloseTask {
reason: Option<String>,
}
impl Runnable for CloseTask {
fn handler(self: Box<Self>) {
impl Task for CloseTask {
fn run(self: Box<Self>) {
let ws = self.address.root();
if ws.ready_state.get() == WebSocketRequestState::Closed {
@ -479,9 +483,9 @@ struct MessageReceivedTask {
message: MessageData,
}
impl Runnable for MessageReceivedTask {
impl Task for MessageReceivedTask {
#[allow(unsafe_code)]
fn handler(self: Box<Self>) {
fn run(self: Box<Self>) {
let ws = self.address.root();
debug!("MessageReceivedTask::handler({:p}): readyState={:?}", &*ws,
ws.ready_state.get());

View file

@ -76,8 +76,8 @@ use script_layout_interface::rpc::{ContentBoxResponse, ContentBoxesResponse, Lay
use script_layout_interface::rpc::{MarginStyleResponse, NodeScrollRootIdResponse};
use script_layout_interface::rpc::{ResolvedStyleResponse, TextIndexResponse};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, ScriptThreadEventCategory};
use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg, Runnable};
use script_thread::{RunnableWrapper, ScriptThread, SendableMainThreadScriptChan};
use script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg, Task};
use script_thread::{ScriptThread, SendableMainThreadScriptChan, TaskCanceller};
use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowserEvent};
use script_traits::{ScriptToConstellationChan, ScriptMsg, ScrollState, TimerEvent, TimerEventId};
use script_traits::{TimerSchedulerMsg, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
@ -1038,8 +1038,8 @@ impl WindowMethods for Window {
}
impl Window {
pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
RunnableWrapper {
pub fn task_canceller(&self) -> TaskCanceller {
TaskCanceller {
cancelled: Some(self.ignore_further_async_events.borrow().clone()),
}
}
@ -1986,9 +1986,9 @@ impl PostMessageHandler {
}
}
impl Runnable for PostMessageHandler {
impl Task for PostMessageHandler {
// https://html.spec.whatwg.org/multipage/#dom-window-postmessage steps 10-12.
fn handler(self: Box<PostMessageHandler>) {
fn run(self: Box<Self>) {
let this = *self;
let window = this.destination.root();
@ -2017,9 +2017,9 @@ impl Runnable for PostMessageHandler {
impl Window {
pub fn post_message(&self, origin: Option<ImmutableOrigin>, data: StructuredCloneData) {
let runnable = PostMessageHandler::new(self, origin, data);
let runnable = self.get_runnable_wrapper().wrap_runnable(box runnable);
let msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::DomEvent, runnable);
let task = PostMessageHandler::new(self, origin, data);
let task = self.task_canceller().wrap_task(box task);
let msg = CommonScriptMsg::Task(ScriptThreadEventCategory::DomEvent, task);
// TODO(#12718): Use the "posted message task source".
let _ = self.script_chan.send(msg);
}

View file

@ -25,7 +25,7 @@ use dom_struct::dom_struct;
use ipc_channel::ipc;
use js::jsapi::{HandleValue, JSAutoCompartment, JSContext, NullHandleValue};
use js::jsval::UndefinedValue;
use script_thread::Runnable;
use script_thread::Task;
use script_traits::WorkerScriptLoadOrigin;
use std::cell::Cell;
use std::sync::{Arc, Mutex};
@ -212,16 +212,16 @@ impl WorkerMessageHandler {
}
}
impl Runnable for WorkerMessageHandler {
fn handler(self: Box<WorkerMessageHandler>) {
impl Task for WorkerMessageHandler {
fn run(self: Box<Self>) {
let this = *self;
Worker::handle_message(this.addr, this.data);
}
}
impl Runnable for SimpleWorkerErrorHandler<Worker> {
impl Task for SimpleWorkerErrorHandler<Worker> {
#[allow(unrooted_must_root)]
fn handler(self: Box<SimpleWorkerErrorHandler<Worker>>) {
fn run(self: Box<Self>) {
let this = *self;
Worker::dispatch_simple_error(this.addr);
}
@ -241,8 +241,8 @@ impl WorkerErrorHandler {
}
}
impl Runnable for WorkerErrorHandler {
fn handler(self: Box<Self>) {
impl Task for WorkerErrorHandler {
fn run(self: Box<Self>) {
let this = *self;
this.address.root().dispatch_error(this.error_info);
}

View file

@ -33,7 +33,7 @@ use js::rust::Runtime;
use net_traits::{IpcSend, load_whole_resource};
use net_traits::request::{CredentialsMode, Destination, RequestInit as NetRequestInit, Type as RequestType};
use script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort, get_reports};
use script_thread::RunnableWrapper;
use script_thread::TaskCanceller;
use script_traits::{TimerEvent, TimerEventId};
use script_traits::WorkerGlobalScopeInit;
use servo_url::{MutableOrigin, ServoUrl};
@ -161,8 +161,8 @@ impl WorkerGlobalScope {
self.worker_id.clone()
}
pub fn get_runnable_wrapper(&self) -> RunnableWrapper {
RunnableWrapper {
pub fn task_canceller(&self) -> TaskCanceller {
TaskCanceller {
cancelled: self.closing.clone(),
}
}
@ -387,8 +387,8 @@ impl WorkerGlobalScope {
pub fn process_event(&self, msg: CommonScriptMsg) {
match msg {
CommonScriptMsg::RunnableMsg(_, runnable) => {
runnable.handler()
CommonScriptMsg::Task(_, task) => {
task.run()
},
CommonScriptMsg::CollectReports(reports_chan) => {
let cx = self.get_cx();

View file

@ -51,9 +51,7 @@ use script_runtime::CommonScriptMsg;
use script_runtime::ScriptThreadEventCategory;
use script_runtime::StackRootTLS;
use script_runtime::new_rt_and_cx;
use script_thread::MainThreadScriptMsg;
use script_thread::Runnable;
use script_thread::ScriptThread;
use script_thread::{MainThreadScriptMsg, ScriptThread, Task};
use servo_rand;
use servo_url::ImmutableOrigin;
use servo_url::ServoUrl;
@ -600,7 +598,7 @@ impl WorkletThread {
debug!("Failed to load script.");
let old_counter = pending_tasks_struct.set_counter_to(-1);
if old_counter > 0 {
self.run_in_script_thread(promise.reject_runnable(Error::Abort));
self.run_in_script_thread(promise.reject_task(Error::Abort));
}
} else {
// Step 5.
@ -610,7 +608,7 @@ impl WorkletThread {
debug!("Resolving promise.");
let msg = MainThreadScriptMsg::WorkletLoaded(pipeline_id);
self.global_init.to_script_thread_sender.send(msg).expect("Worklet thread outlived script thread.");
self.run_in_script_thread(promise.resolve_runnable(()));
self.run_in_script_thread(promise.resolve_task(()));
}
}
}
@ -645,11 +643,11 @@ impl WorkletThread {
}
}
/// Run a runnable in the main script thread.
fn run_in_script_thread<R>(&self, runnable: R) where
R: 'static + Send + Runnable,
/// Run a task in the main script thread.
fn run_in_script_thread<T>(&self, task: T) where
T: 'static + Send + Task,
{
let msg = CommonScriptMsg::RunnableMsg(ScriptThreadEventCategory::WorkletEvent, box runnable);
let msg = CommonScriptMsg::Task(ScriptThreadEventCategory::WorkletEvent, box task);
let msg = MainThreadScriptMsg::Common(msg);
self.global_init.to_script_thread_sender.send(msg).expect("Worklet thread outlived script thread.");
}

View file

@ -24,9 +24,7 @@ use profile_traits::mem;
use profile_traits::time;
use script_layout_interface::message::Msg;
use script_runtime::ScriptThreadEventCategory;
use script_thread::MainThreadScriptMsg;
use script_thread::Runnable;
use script_thread::ScriptThread;
use script_thread::{MainThreadScriptMsg, ScriptThread, Task};
use script_traits::ScriptMsg;
use script_traits::ScriptToConstellationChan;
use script_traits::TimerSchedulerMsg;
@ -95,28 +93,29 @@ impl WorkletGlobalScope {
self.globalscope.evaluate_js_on_global_with_result(&*script, rval.handle_mut())
}
/// Run a runnable in the main script thread.
pub fn run_in_script_thread<R>(&self, runnable: R) where
R: 'static + Send + Runnable,
/// Run a task in the main script thread.
pub fn run_in_script_thread<T>(&self, task: T)
where
T: 'static + Send + Task,
{
self.to_script_thread_sender
.send(MainThreadScriptMsg::MainThreadRunnable(
.send(MainThreadScriptMsg::MainThreadTask(
ScriptThreadEventCategory::WorkletEvent,
box runnable,
box task,
))
.expect("Worklet thread outlived script thread.");
}
/// Send a message to layout.
pub fn send_to_layout(&self, msg: Msg) {
struct RunnableMsg(PipelineId, Msg);
impl Runnable for RunnableMsg {
fn main_thread_handler(self: Box<Self>, script_thread: &ScriptThread) {
struct SendToLayoutTask(PipelineId, Msg);
impl Task for SendToLayoutTask {
fn run_with_script_thread(self: Box<Self>, script_thread: &ScriptThread) {
script_thread.send_to_layout(self.0, self.1);
}
}
let pipeline_id = self.globalscope.pipeline_id();
self.run_in_script_thread(RunnableMsg(pipeline_id, msg));
self.run_in_script_thread(SendToLayoutTask(pipeline_id, msg));
}
/// The base URL of this global.

View file

@ -261,7 +261,7 @@ impl XMLHttpRequest {
let listener = NetworkListener {
context: context,
task_source: task_source,
wrapper: Some(global.get_runnable_wrapper())
canceller: Some(global.task_canceller())
};
ROUTER.add_route(action_receiver.to_opaque(), box move |message| {
listener.notify_fetch(message.to().unwrap());