servo: Merge #8853 - Split fn script_chan into 5 different task channel fn (from KiChjang:generic-task-sources); r=jdm
authorKeith Yeung <kungfukeith11@gmail.com>
Mon, 07 Dec 2015 07:16:40 +0500
changeset 337726 199a30bd5818b2e419919e66b6e795bce6e9e669
parent 337725 ac06ab7fc9b87e242e7cdc8c4f40e6308d139f74
child 337727 4abc2e566413d827c76fa23f65640c271215bb91
push id31307
push usergszorc@mozilla.com
push dateSat, 04 Feb 2017 00:59:06 +0000
treeherdermozilla-central@94079d43835f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
servo: Merge #8853 - Split fn script_chan into 5 different task channel fn (from KiChjang:generic-task-sources); r=jdm Partial #7959. Source-Repo: https://github.com/servo/servo Source-Revision: ef000a458a52051b55b65e254ff9fe1a55835d04
servo/components/script/dom/bindings/global.rs
servo/components/script/dom/filereader.rs
servo/components/script/dom/htmlimageelement.rs
servo/components/script/dom/htmllinkelement.rs
servo/components/script/dom/htmlscriptelement.rs
servo/components/script/dom/htmltextareaelement.rs
servo/components/script/dom/storage.rs
servo/components/script/dom/websocket.rs
servo/components/script/dom/window.rs
servo/components/script/dom/worker.rs
servo/components/script/dom/xmlhttprequest.rs
--- a/servo/components/script/dom/bindings/global.rs
+++ b/servo/components/script/dom/bindings/global.rs
@@ -150,19 +150,55 @@ impl<'a> GlobalRef<'a> {
         match *self {
             GlobalRef::Window(ref window) => window.get_url(),
             GlobalRef::Worker(ref worker) => worker.get_url().clone(),
         }
     }
 
     /// `ScriptChan` used to send messages to the event loop of this global's
     /// thread.
-    pub fn script_chan(&self) -> Box<ScriptChan + Send> {
+    pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> {
+        match *self {
+            GlobalRef::Window(ref window) => window.dom_manipulation_task_source(),
+            GlobalRef::Worker(ref worker) => worker.script_chan(),
+        }
+    }
+
+    /// `ScriptChan` used to send messages to the event loop of this global's
+    /// thread.
+    pub fn user_interaction_task_source(&self) -> Box<ScriptChan + Send> {
+        match *self {
+            GlobalRef::Window(ref window) => window.user_interaction_task_source(),
+            GlobalRef::Worker(ref worker) => worker.script_chan(),
+        }
+    }
+
+    /// `ScriptChan` used to send messages to the event loop of this global's
+    /// thread.
+    pub fn networking_task_source(&self) -> Box<ScriptChan + Send> {
         match *self {
-            GlobalRef::Window(ref window) => window.script_chan(),
+            GlobalRef::Window(ref window) => window.networking_task_source(),
+            GlobalRef::Worker(ref worker) => worker.script_chan(),
+        }
+    }
+
+    /// `ScriptChan` used to send messages to the event loop of this global's
+    /// thread.
+    pub fn history_traversal_task_source(&self) -> Box<ScriptChan + Send> {
+        match *self {
+            GlobalRef::Window(ref window) => window.history_traversal_task_source(),
+            GlobalRef::Worker(ref worker) => worker.script_chan(),
+        }
+    }
+
+    /// `ScriptChan` used to send messages to the event loop of this global's
+    /// thread.
+    pub fn file_reading_task_source(&self) -> Box<ScriptChan + Send> {
+        match *self {
+            GlobalRef::Window(ref window) => window.file_reading_task_source(),
             GlobalRef::Worker(ref worker) => worker.script_chan(),
         }
     }
 
     /// Create a new sender/receiver pair that can be used to implement an on-demand
     /// event loop. Used for implementing web APIs that require blocking semantics
     /// without resorting to nested event loops.
     pub fn new_script_pair(&self) -> (Box<ScriptChan + Send>, Box<ScriptPort + Send>) {
--- a/servo/components/script/dom/filereader.rs
+++ b/servo/components/script/dom/filereader.rs
@@ -355,20 +355,20 @@ impl FileReader {
 
         // Step 4
         let (send, bytes) = mpsc::channel();
         blob.read_out_buffer(send);
         let type_ = blob.Type();
 
         let load_data = ReadMetaData::new(String::from(type_), label.map(String::from), function);
 
-        let fr = Trusted::new(global.get_cx(), self, global.script_chan());
+        let fr = Trusted::new(global.get_cx(), self, global.file_reading_task_source());
         let gen_id = self.generation_id.get();
 
-        let script_chan = global.script_chan();
+        let script_chan = global.file_reading_task_source();
 
         spawn_named("file reader async operation".to_owned(), move || {
             perform_annotated_read_operation(gen_id, load_data, bytes, fr, script_chan)
         });
         Ok(())
     }
 
     fn change_ready_state(&self, state: FileReaderReadyState) {
--- a/servo/components/script/dom/htmlimageelement.rs
+++ b/servo/components/script/dom/htmlimageelement.rs
@@ -101,19 +101,19 @@ impl HTMLImageElement {
                 *self.image.borrow_mut() = None;
             }
             Some((src, base_url)) => {
                 let img_url = UrlParser::new().base_url(&base_url).parse(&src);
                 // FIXME: handle URL parse errors more gracefully.
                 let img_url = img_url.unwrap();
                 *self.url.borrow_mut() = Some(img_url.clone());
 
-                let trusted_node = Trusted::new(window.get_cx(), self, window.script_chan());
+                let trusted_node = Trusted::new(window.get_cx(), self, window.networking_task_source());
                 let (responder_sender, responder_receiver) = ipc::channel().unwrap();
-                let script_chan = window.script_chan();
+                let script_chan = window.networking_task_source();
                 let wrapper = window.get_runnable_wrapper();
                 ROUTER.add_route(responder_receiver.to_opaque(), box move |message| {
                     // Return the image via a message to the script task, which marks the element
                     // as dirty and triggers a reflow.
                     let image_response = message.to().unwrap();
                     let runnable = ImageResponseHandlerRunnable::new(
                         trusted_node.clone(), image_response);
                     let runnable = wrapper.wrap_runnable(runnable);
--- a/servo/components/script/dom/htmllinkelement.rs
+++ b/servo/components/script/dom/htmllinkelement.rs
@@ -192,17 +192,17 @@ impl HTMLLinkElement {
                     Some(ref value) => &***value,
                     None => "",
                 };
                 let mut css_parser = CssParser::new(&mq_str);
                 let media = parse_media_query_list(&mut css_parser);
 
                 // TODO: #8085 - Don't load external stylesheets if the node's mq doesn't match.
                 let doc = window.Document();
-                let script_chan = window.script_chan();
+                let script_chan = window.networking_task_source();
                 let elem = Trusted::new(window.get_cx(), self, script_chan.clone());
 
                 let context = Arc::new(Mutex::new(StylesheetContext {
                     elem: elem,
                     media: Some(media),
                     data: vec!(),
                     metadata: None,
                     url: url.clone(),
--- a/servo/components/script/dom/htmlscriptelement.rs
+++ b/servo/components/script/dom/htmlscriptelement.rs
@@ -211,17 +211,19 @@ impl HTMLScriptElement {
             return NextParserState::Continue;
         }
 
         // Step 11.
         if !document_from_node_ref.is_scripting_enabled() {
             return NextParserState::Continue;
         }
 
-        // Step 12.
+        // TODO: Step 12.
+
+        // Step 13.
         let for_attribute = element.get_attribute(&ns!(), &atom!("for"));
         let event_attribute = element.get_attribute(&ns!(), &atom!("event"));
         match (for_attribute.r(), event_attribute.r()) {
             (Some(for_attribute), Some(event_attribute)) => {
                 let for_value = for_attribute.value().to_ascii_lowercase();
                 let for_value = for_value.trim_matches(HTML_SPACE_CHARACTERS);
                 if for_value != "window" {
                     return NextParserState::Continue;
@@ -231,56 +233,55 @@ impl HTMLScriptElement {
                 let event_value = event_value.trim_matches(HTML_SPACE_CHARACTERS);
                 if event_value != "onload" && event_value != "onload()" {
                     return NextParserState::Continue;
                 }
             },
             (_, _) => (),
         }
 
-        // Step 13.
+        // Step 14.
         if let Some(ref charset) = element.get_attribute(&ns!(), &atom!("charset")) {
             if let Some(encodingRef) = encoding_from_whatwg_label(&charset.Value()) {
                 *self.block_character_encoding.borrow_mut() = encodingRef;
             }
         }
 
-        // Step 14.
+        // Step 15.
         let window = window_from_node(self);
         let window = window.r();
         let base_url = window.get_url();
-        let deferred = element.has_attribute(&atom!("defer"));
 
         let is_external = match element.get_attribute(&ns!(), &atom!("src")) {
-            // Step 14.
+            // Step 15.
             Some(ref src) => {
-                // Step 14.1
+                // Step 15.1
                 let src = src.value();
 
-                // Step 14.2
+                // Step 15.2
                 if src.is_empty() {
                     self.queue_error_event();
                     return NextParserState::Continue;
                 }
 
-                // Step 14.3
+                // Step 15.3
                 match UrlParser::new().base_url(&base_url).parse(&src) {
                     Err(_) => {
-                        // Step 14.4
+                        // Step 15.4
                         error!("error parsing URL for script {}", &**src);
                         self.queue_error_event();
                         return NextParserState::Continue;
                     }
                     Ok(url) => {
-                        // Step 14.5
+                        // Step 15.5
                         // TODO: Do a potentially CORS-enabled fetch with the mode being the current
                         // state of the element's `crossorigin` content attribute, the origin being
                         // the origin of the script element's node document, and the default origin
                         // behaviour set to taint.
-                        let script_chan = window.script_chan();
+                        let script_chan = window.networking_task_source();
                         let elem = Trusted::new(window.get_cx(), self, script_chan.clone());
 
                         let context = Arc::new(Mutex::new(ScriptContext {
                             elem: elem,
                             data: vec!(),
                             metadata: None,
                             url: url.clone(),
                         }));
@@ -300,50 +301,51 @@ impl HTMLScriptElement {
                         doc.load_async(LoadType::Script(url), response_target);
                     }
                 }
                 true
             },
             None => false,
         };
 
-        // Step 15.
-        // Step 15.a, has src, has defer, was parser-inserted, is not async.
+        // Step 16.
+        let deferred = element.has_attribute(&atom!("defer"));
+        // Step 16.a, has src, has defer, was parser-inserted, is not async.
         if is_external &&
            deferred &&
            was_parser_inserted &&
            !async {
             doc.add_deferred_script(self);
             // Second part implemented in Document::process_deferred_scripts.
             return NextParserState::Continue;
-        // Step 15.b, has src, was parser-inserted, is not async.
+        // Step 16.b, has src, was parser-inserted, is not async.
         } else if is_external &&
                   was_parser_inserted &&
                   !async {
             doc.set_pending_parsing_blocking_script(Some(self));
             // Second part implemented in the load result handler.
-        // Step 15.c, doesn't have src, was parser-inserted, is blocked on stylesheet.
+        // Step 16.c, doesn't have src, was parser-inserted, is blocked on stylesheet.
         } else if !is_external &&
                   was_parser_inserted &&
                   // TODO: check for script nesting levels.
                   doc.get_script_blocking_stylesheets_count() > 0 {
             doc.set_pending_parsing_blocking_script(Some(self));
             *self.load.borrow_mut() = Some(ScriptOrigin::Internal(text, base_url));
             self.ready_to_be_parser_executed.set(true);
-        // Step 15.d, has src, isn't async, isn't non-blocking.
+        // Step 16.d, has src, isn't async, isn't non-blocking.
         } else if is_external &&
                   !async &&
                   !self.non_blocking.get() {
             doc.push_asap_in_order_script(self);
             // Second part implemented in Document::process_asap_scripts.
-        // Step 15.e, has src.
+        // Step 16.e, has src.
         } else if is_external {
             doc.add_asap_script(self);
             // Second part implemented in Document::process_asap_scripts.
-        // Step 15.f, otherwise.
+        // Step 16.f, otherwise.
         } else {
             assert!(!text.is_empty());
             self.ready_to_be_parser_executed.set(true);
             *self.load.borrow_mut() = Some(ScriptOrigin::Internal(text, base_url));
             self.execute();
             return NextParserState::Continue;
         }
         // TODO: make this suspension happen automatically.
@@ -448,30 +450,30 @@ impl HTMLScriptElement {
 
         // Step 2.b.9.
         self.dispatch_after_script_execute_event();
 
         // Step 2.b.10.
         if external {
             self.dispatch_load_event();
         } else {
-            let chan = window.script_chan();
+            let chan = window.dom_manipulation_task_source();
             let handler = Trusted::new(window.get_cx(), self, chan.clone());
             let dispatcher = box EventDispatcher {
                 element: handler,
                 is_error: false,
             };
             chan.send(CommonScriptMsg::RunnableMsg(ScriptEvent, dispatcher)).unwrap();
         }
     }
 
     pub fn queue_error_event(&self) {
         let window = window_from_node(self);
         let window = window.r();
-        let chan = window.script_chan();
+        let chan = window.dom_manipulation_task_source();
         let handler = Trusted::new(window.get_cx(), self, chan.clone());
         let dispatcher = box EventDispatcher {
             element: handler,
             is_error: true,
         };
         chan.send(CommonScriptMsg::RunnableMsg(ScriptEvent, dispatcher)).unwrap();
     }
 
--- a/servo/components/script/dom/htmltextareaelement.rs
+++ b/servo/components/script/dom/htmltextareaelement.rs
@@ -338,17 +338,17 @@ impl VirtualMethods for HTMLTextAreaElem
                 match self.textinput.borrow_mut().handle_keydown(kevent) {
                     KeyReaction::TriggerDefaultAction => (),
                     KeyReaction::DispatchInput => {
                         self.value_changed.set(true);
 
                         if event.IsTrusted() {
                             let window = window_from_node(self);
                             let window = window.r();
-                            let chan = window.script_chan();
+                            let chan = window.user_interaction_task_source();
                             let handler = Trusted::new(window.get_cx(), self, chan.clone());
                             let dispatcher = ChangeEventRunnable {
                                 element: handler,
                             };
                             let _ = chan.send(CommonScriptMsg::RunnableMsg(InputEvent, box dispatcher));
                         }
 
                         self.force_relayout();
--- a/servo/components/script/dom/storage.rs
+++ b/servo/components/script/dom/storage.rs
@@ -150,17 +150,17 @@ impl StorageMethods for Storage {
 
 impl Storage {
     /// https://html.spec.whatwg.org/multipage/#send-a-storage-notification
     fn broadcast_change_notification(&self, key: Option<String>, old_value: Option<String>,
                                      new_value: Option<String>) {
         let global_root = self.global.root();
         let global_ref = global_root.r();
         let main_script_chan = global_ref.as_window().main_thread_script_chan();
-        let script_chan = global_ref.script_chan();
+        let script_chan = global_ref.dom_manipulation_task_source();
         let trusted_storage = Trusted::new(global_ref.get_cx(), self,
                                            script_chan.clone());
         main_script_chan.send(MainThreadScriptMsg::MainThreadRunnableMsg(
             box StorageEventRunnable::new(trusted_storage, key, old_value, new_value))).unwrap();
     }
 }
 
 pub struct StorageEventRunnable {
--- a/servo/components/script/dom/websocket.rs
+++ b/servo/components/script/dom/websocket.rs
@@ -249,20 +249,20 @@ impl WebSocket {
                 return Err(Error::Syntax);
             }
         }
 
         // Step 6: Origin.
 
         // Step 7.
         let ws = WebSocket::new(global, resource_url.clone());
-        let address = Trusted::new(global.get_cx(), ws.r(), global.script_chan());
+        let address = Trusted::new(global.get_cx(), ws.r(), global.networking_task_source());
 
         let origin = global.get_url().serialize();
-        let sender = global.script_chan();
+        let sender = global.networking_task_source();
         spawn_named(format!("WebSocket connection to {}", ws.Url()), move || {
             // Step 8: Protocols.
 
             // Step 9.
             let channel = establish_a_websocket_connection(&resource_url, net_url, origin);
             let (ws_sender, mut receiver) = match channel {
                 Ok(channel) => channel,
                 Err(e) => {
@@ -323,17 +323,17 @@ impl WebSocket {
             WebSocketRequestState::Connecting => {
                 return Err(Error::InvalidState);
             },
             WebSocketRequestState::Open => false,
             WebSocketRequestState::Closing | WebSocketRequestState::Closed => true,
         };
 
         let global = self.global.root();
-        let chan = global.r().script_chan();
+        let chan = global.r().networking_task_source();
         let address = Trusted::new(global.r().get_cx(), self, chan.clone());
 
         let new_buffer_amount = (self.buffered_amount.get() as u64) + data_byte_len;
         if new_buffer_amount > (u32::max_value() as u64) {
             self.buffered_amount.set(u32::max_value());
             self.full.set(true);
 
             let _ = self.Close(None, None);
--- a/servo/components/script/dom/window.rs
+++ b/servo/components/script/dom/window.rs
@@ -232,17 +232,38 @@ impl Window {
             self.ignore_further_async_events.store(true, Ordering::Relaxed);
         }
     }
 
     pub fn get_cx(&self) -> *mut JSContext {
         self.js_runtime.borrow().as_ref().unwrap().cx()
     }
 
-    pub fn script_chan(&self) -> Box<ScriptChan + Send> {
+    pub fn dom_manipulation_task_source(&self) -> Box<ScriptChan + Send> {
+        // FIXME: Use a different channel instead of the generic script_chan
+        self.script_chan.clone()
+    }
+
+    pub fn user_interaction_task_source(&self) -> Box<ScriptChan + Send> {
+        // FIXME: Use a different channel instead of the generic script_chan
+        self.script_chan.clone()
+    }
+
+    pub fn networking_task_source(&self) -> Box<ScriptChan + Send> {
+        // FIXME: Use a different channel instead of the generic script_chan
+        self.script_chan.clone()
+    }
+
+    pub fn history_traversal_task_source(&self) -> Box<ScriptChan + Send> {
+        // FIXME: Use a different channel instead of the generic script_chan
+        self.script_chan.clone()
+    }
+
+    pub fn file_reading_task_source(&self) -> Box<ScriptChan + Send> {
+        // FIXME: Use a different channel instead of the generic script_chan
         self.script_chan.clone()
     }
 
     pub fn main_thread_script_chan(&self) -> &Sender<MainThreadScriptMsg> {
         let MainThreadScriptChan(ref sender) = self.script_chan;
         sender
     }
 
--- a/servo/components/script/dom/worker.rs
+++ b/servo/components/script/dom/worker.rs
@@ -70,17 +70,17 @@ impl Worker {
         };
 
         let resource_task = global.resource_task();
         let constellation_chan = global.constellation_chan();
         let scheduler_chan = global.scheduler_chan();
 
         let (sender, receiver) = channel();
         let worker = Worker::new(global, sender.clone());
-        let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.script_chan());
+        let worker_ref = Trusted::new(global.get_cx(), worker.r(), global.dom_manipulation_task_source());
         let worker_id = global.get_next_worker_id();
 
         let (devtools_sender, devtools_receiver) = ipc::channel().unwrap();
         let optional_sender = match global.devtools_chan() {
             Some(ref chan) => {
                 let pipeline_id = global.pipeline();
                 let title = format!("Worker for {}", worker_url);
                 let page_info = DevtoolsPageInfo {
@@ -101,17 +101,17 @@ impl Worker {
             to_devtools_sender: global.devtools_chan(),
             from_devtools_sender: optional_sender,
             constellation_chan: constellation_chan,
             scheduler_chan: scheduler_chan,
             worker_id: worker_id,
         };
         DedicatedWorkerGlobalScope::run_worker_scope(
             init, worker_url, global.pipeline(), devtools_receiver, worker_ref,
-            global.script_chan(), sender, receiver);
+            global.dom_manipulation_task_source(), sender, receiver);
 
         Ok(worker)
     }
 
     pub fn handle_message(address: TrustedWorkerAddress,
                           data: StructuredCloneData) {
         let worker = address.root();
 
@@ -145,17 +145,17 @@ impl Worker {
         errorevent.upcast::<Event>().fire(worker.upcast());
     }
 }
 
 impl WorkerMethods for Worker {
     // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage
     fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult {
         let data = try!(StructuredCloneData::write(cx, message));
-        let address = Trusted::new(cx, self, self.global.root().r().script_chan().clone());
+        let address = Trusted::new(cx, self, self.global.root().r().dom_manipulation_task_source().clone());
         self.sender.send((address, WorkerScriptMsg::DOMMessage(data))).unwrap();
         Ok(())
     }
 
     // https://html.spec.whatwg.org/multipage/#handler-dedicatedworkerglobalscope-onmessage
     event_handler!(message, GetOnmessage, SetOnmessage);
 
     // https://html.spec.whatwg.org/multipage/#handler-workerglobalscope-onerror
--- a/servo/components/script/dom/xmlhttprequest.rs
+++ b/servo/components/script/dom/xmlhttprequest.rs
@@ -979,17 +979,17 @@ impl XMLHttpRequest {
                 }
             }
         }
 
         // Sets up the object to timeout in a given number of milliseconds
         // This will cancel all previous timeouts
         let global = self.global.root();
         let callback = ScheduledXHRTimeout {
-            xhr: Trusted::new(global.r().get_cx(), self, global.r().script_chan()),
+            xhr: Trusted::new(global.r().get_cx(), self, global.r().networking_task_source()),
             generation_id: self.generation_id.get(),
         };
         let duration = Length::new(duration_ms as u64);
         *self.timeout_cancel.borrow_mut() = Some(global.r().schedule_callback(box callback, duration));
     }
 
     fn cancel_timeout(&self) {
         if let Some(handle) = self.timeout_cancel.borrow_mut().take() {
@@ -1051,31 +1051,31 @@ impl XMLHttpRequest {
                 // Happens in case of cross-origin non-http URIs
                 self.process_partial_response(XHRProgress::Errored(
                     self.generation_id.get(), Error::Network));
                 return Err(Error::Network);
             }
             Ok(req) => req,
         };
 
-        let xhr = Trusted::new(global.get_cx(), self, global.script_chan());
+        let xhr = Trusted::new(global.get_cx(), self, global.networking_task_source());
 
         let context = Arc::new(Mutex::new(XHRContext {
             xhr: xhr,
             cors_request: cors_request.clone(),
             gen_id: self.generation_id.get(),
             buf: DOMRefCell::new(vec!()),
             sync_status: DOMRefCell::new(None),
         }));
 
         let (script_chan, script_port) = if self.sync.get() {
             let (tx, rx) = global.new_script_pair();
             (tx, Some(rx))
         } else {
-            (global.script_chan(), None)
+            (global.networking_task_source(), None)
         };
 
         let resource_task = global.resource_task();
         if let Some(req) = cors_request {
             XMLHttpRequest::check_cors(context.clone(), load_data, req.clone(),
                                        script_chan.clone(), resource_task);
         } else {
             XMLHttpRequest::initiate_async_xhr(context.clone(), script_chan,