aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/script_thread.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/script_thread.rs')
-rw-r--r--components/script/script_thread.rs159
1 files changed, 87 insertions, 72 deletions
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index f55d9279138..447b6775bdc 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -32,7 +32,7 @@ use dom::bindings::codegen::Bindings::TransitionEventBinding::TransitionEventIni
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::conversions::{ConversionResult, FromJSValConvertible, StringificationBehavior};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, MutNullableHeap, Root, RootCollection};
+use dom::bindings::js::{JS, MutNullableJS, Root, RootCollection};
use dom::bindings::js::{RootCollectionPtr, RootedReference};
use dom::bindings::num::Finite;
use dom::bindings::refcounted::Trusted;
@@ -91,6 +91,7 @@ use script_traits::CompositorEvent::{KeyEvent, MouseButtonEvent, MouseMoveEvent,
use script_traits::CompositorEvent::{TouchEvent, TouchpadPressureEvent};
use script_traits::webdriver_msg::WebDriverScriptCommand;
use serviceworkerjob::{Job, JobQueue, AsyncJobHandler, FinishJobHandler, InvokeType, SettleType};
+use servo_config::opts;
use servo_url::ServoUrl;
use std::cell::Cell;
use std::collections::{hash_map, HashMap, HashSet};
@@ -101,6 +102,7 @@ use std::result::Result;
use std::sync::{Arc, Mutex};
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{Receiver, Select, Sender, channel};
+use std::thread;
use style::context::ReflowGoal;
use style::dom::{TNode, UnsafeNode};
use style::thread_state;
@@ -112,8 +114,6 @@ use task_source::networking::NetworkingTaskSource;
use task_source::user_interaction::{UserInteractionTask, UserInteractionTaskSource};
use time::Tm;
use url::Position;
-use util::opts;
-use util::thread;
use webdriver_handlers;
thread_local!(pub static STACK_ROOTS: Cell<Option<RootCollectionPtr>> = Cell::new(None));
@@ -461,7 +461,7 @@ pub struct ScriptThread {
js_runtime: Rc<Runtime>,
/// The topmost element over the mouse.
- topmost_mouse_over_target: MutNullableHeap<JS<Element>>,
+ topmost_mouse_over_target: MutNullableJS<Element>,
/// List of pipelines that have been owned and closed by this script thread.
closed_pipelines: DOMRefCell<HashSet<PipelineId>>,
@@ -498,13 +498,10 @@ impl<'a> ScriptMemoryFailsafe<'a> {
impl<'a> Drop for ScriptMemoryFailsafe<'a> {
#[allow(unrooted_must_root)]
fn drop(&mut self) {
- match self.owner {
- Some(owner) => {
- for (_, document) in owner.documents.borrow().iter() {
- document.window().clear_js_runtime_for_script_deallocation();
- }
+ if let Some(owner) = self.owner {
+ for (_, document) in owner.documents.borrow().iter() {
+ document.window().clear_js_runtime_for_script_deallocation();
}
- None => (),
}
}
}
@@ -519,8 +516,7 @@ impl ScriptThreadFactory for ScriptThread {
let (sender, receiver) = channel();
let layout_chan = sender.clone();
- thread::spawn_named(format!("ScriptThread {:?}", state.id),
- move || {
+ thread::Builder::new().name(format!("ScriptThread {:?}", state.id)).spawn(move || {
thread_state::initialize(thread_state::SCRIPT);
PipelineNamespace::install(state.pipeline_namespace_id);
FrameId::install(state.top_level_frame_id);
@@ -553,7 +549,7 @@ impl ScriptThreadFactory for ScriptThread {
// This must always be the very last operation performed before the thread completes
failsafe.neuter();
- });
+ }).expect("Thread spawning failed");
(sender, receiver)
}
@@ -686,7 +682,7 @@ impl ScriptThread {
devtools_sender: ipc_devtools_sender,
js_runtime: Rc::new(runtime),
- topmost_mouse_over_target: MutNullableHeap::new(Default::default()),
+ topmost_mouse_over_target: MutNullableJS::new(Default::default()),
closed_pipelines: DOMRefCell::new(HashSet::new()),
scheduler_chan: state.scheduler_chan,
@@ -726,10 +722,8 @@ impl ScriptThread {
for (id, document) in self.documents.borrow().iter() {
// Only process a resize if layout is idle.
- let resize_event = document.window().steal_resize_event();
- match resize_event {
- Some((size, size_type)) => resizes.push((id, size, size_type)),
- None => ()
+ if let Some((size, size_type)) = document.window().steal_resize_event() {
+ resizes.push((id, size, size_type));
}
}
@@ -1050,8 +1044,11 @@ impl ScriptThread {
TimerSource::FromWorker => panic!("Worker timeouts must not be sent to script thread"),
};
- let window = self.documents.borrow().find_window(pipeline_id)
- .expect("ScriptThread: received fire timer msg for a pipeline not in this script thread. This is a bug.");
+ let window = self.documents.borrow().find_window(pipeline_id);
+ let window = match window {
+ Some(w) => w,
+ None => return warn!("Received fire timer msg for a closed pipeline {}.", pipeline_id),
+ };
window.handle_fire_timer(id);
}
@@ -1143,7 +1140,8 @@ impl ScriptThread {
}
fn handle_resize(&self, id: PipelineId, size: WindowSizeData, size_type: WindowSizeType) {
- if let Some(ref window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(ref window) = window {
window.set_resize_event(size, size_type);
return;
}
@@ -1156,7 +1154,8 @@ impl ScriptThread {
}
fn handle_viewport(&self, id: PipelineId, rect: Rect<f32>) {
- if let Some(document) = self.documents.borrow().find_document(id) {
+ let document = self.documents.borrow().find_document(id);
+ if let Some(document) = document {
if document.window().set_page_clip_rect_with_new_viewport(rect) {
self.rebuild_and_force_reflow(&document, ReflowReason::Viewport);
}
@@ -1173,7 +1172,7 @@ impl ScriptThread {
fn handle_set_scroll_state(&self,
id: PipelineId,
scroll_states: &[(UntrustedNodeAddress, Point2D<f32>)]) {
- let window = match self.documents.borrow().find_window(id) {
+ let window = match { self.documents.borrow().find_window(id) } {
Some(window) => window,
None => return warn!("Set scroll state message sent to nonexistent pipeline: {:?}", id),
};
@@ -1241,7 +1240,7 @@ impl ScriptThread {
}
fn handle_loads_complete(&self, pipeline: PipelineId) {
- let doc = match self.documents.borrow().find_document(pipeline) {
+ let doc = match { self.documents.borrow().find_document(pipeline) } {
Some(doc) => doc,
None => return warn!("Message sent to closed pipeline {}.", pipeline),
};
@@ -1296,7 +1295,8 @@ impl ScriptThread {
/// To slow/speed up timers and manage any other script thread resource based on visibility.
/// Returns true if successful.
fn alter_resource_utilization(&self, id: PipelineId, visible: bool) -> bool {
- if let Some(window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(window) = window {
if visible {
window.upcast::<GlobalScope>().speed_up_timers();
} else {
@@ -1309,7 +1309,8 @@ impl ScriptThread {
/// Updates iframe element after a change in visibility
fn handle_visibility_change_complete_msg(&self, parent_pipeline_id: PipelineId, id: FrameId, visible: bool) {
- if let Some(iframe) = self.documents.borrow().find_iframe(parent_pipeline_id, id) {
+ let iframe = self.documents.borrow().find_iframe(parent_pipeline_id, id);
+ if let Some(iframe) = iframe {
iframe.change_visibility_status(visible);
}
}
@@ -1337,7 +1338,8 @@ impl ScriptThread {
/// Handles freeze message
fn handle_freeze_msg(&self, id: PipelineId) {
- if let Some(window) = self.documents.borrow().find_window(id) {
+ let window = self.documents.borrow().find_window(id);
+ if let Some(window) = window {
window.upcast::<GlobalScope>().suspend();
return;
}
@@ -1351,7 +1353,8 @@ impl ScriptThread {
/// Handles thaw message
fn handle_thaw_msg(&self, id: PipelineId) {
- if let Some(document) = self.documents.borrow().find_document(id) {
+ let document = self.documents.borrow().find_document(id);
+ if let Some(document) = document {
if let Some(context) = document.browsing_context() {
let needed_reflow = context.set_reflow_status(false);
if needed_reflow {
@@ -1402,14 +1405,16 @@ impl ScriptThread {
parent_pipeline_id: PipelineId,
frame_id: Option<FrameId>,
event: MozBrowserEvent) {
- match self.documents.borrow().find_document(parent_pipeline_id) {
- None => warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
- Some(doc) => match frame_id {
- None => doc.window().dispatch_mozbrowser_event(event),
- Some(frame_id) => match doc.find_iframe(frame_id) {
- None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id),
- Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
- },
+ let doc = match { self.documents.borrow().find_document(parent_pipeline_id) } {
+ None => return warn!("Mozbrowser event after pipeline {:?} closed.", parent_pipeline_id),
+ Some(doc) => doc,
+ };
+
+ match frame_id {
+ None => doc.window().dispatch_mozbrowser_event(event),
+ Some(frame_id) => match doc.find_iframe(frame_id) {
+ None => warn!("Mozbrowser event after iframe {:?}/{:?} closed.", parent_pipeline_id, frame_id),
+ Some(frame_element) => frame_element.dispatch_mozbrowser_event(event),
},
}
}
@@ -1418,7 +1423,8 @@ impl ScriptThread {
parent_pipeline_id: PipelineId,
frame_id: FrameId,
new_pipeline_id: PipelineId) {
- if let Some(frame_element) = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id) {
+ let frame_element = self.documents.borrow().find_iframe(parent_pipeline_id, frame_id);
+ if let Some(frame_element) = frame_element {
frame_element.update_pipeline_id(new_pipeline_id);
}
}
@@ -1487,13 +1493,14 @@ impl ScriptThread {
Some(r) => r,
None => return
};
- if let Some(window) = self.documents.borrow().find_window(pipeline_id) {
- let script_url = maybe_registration.get_installed().get_script_url();
- let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url);
- let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone()));
- } else {
- warn!("Registration failed for {}", scope);
- }
+ let window = match { self.documents.borrow().find_window(pipeline_id) } {
+ Some(window) => window,
+ None => return warn!("Registration failed for {}", scope),
+ };
+
+ let script_url = maybe_registration.get_installed().get_script_url();
+ let scope_things = ServiceWorkerRegistration::create_scope_things(window.upcast(), script_url);
+ let _ = self.constellation_chan.send(ConstellationMsg::RegisterServiceWorker(scope_things, scope.clone()));
}
pub fn dispatch_job_queue(&self, job_handler: Box<AsyncJobHandler>) {
@@ -1544,7 +1551,7 @@ impl ScriptThread {
/// Handles a request for the window title.
fn handle_get_title_msg(&self, pipeline_id: PipelineId) {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -1601,7 +1608,7 @@ impl ScriptThread {
/// Handles when layout thread finishes all animation in one tick
fn handle_tick_all_animations(&self, id: PipelineId) {
- let document = match self.documents.borrow().find_document(id) {
+ let document = match { self.documents.borrow().find_document(id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", id),
};
@@ -1642,7 +1649,8 @@ impl ScriptThread {
/// Handles a Web font being loaded. Does nothing if the page no longer exists.
fn handle_web_font_loaded(&self, pipeline_id: PipelineId) {
- if let Some(document) = self.documents.borrow().find_document(pipeline_id) {
+ let document = self.documents.borrow().find_document(pipeline_id);
+ if let Some(document) = document {
self.rebuild_and_force_reflow(&document, ReflowReason::WebFontLoaded);
}
}
@@ -1650,12 +1658,14 @@ impl ScriptThread {
/// Notify a window of a storage event
fn handle_storage_event(&self, pipeline_id: PipelineId, storage_type: StorageType, url: ServoUrl,
key: Option<String>, old_value: Option<String>, new_value: Option<String>) {
- let storage = match self.documents.borrow().find_window(pipeline_id) {
+ let window = match { self.documents.borrow().find_window(pipeline_id) } {
None => return warn!("Storage event sent to closed pipeline {}.", pipeline_id),
- Some(window) => match storage_type {
- StorageType::Local => window.LocalStorage(),
- StorageType::Session => window.SessionStorage(),
- },
+ Some(window) => window,
+ };
+
+ let storage = match storage_type {
+ StorageType::Local => window.LocalStorage(),
+ StorageType::Session => window.SessionStorage(),
};
storage.queue_storage_event(url, key, old_value, new_value);
@@ -1908,7 +1918,7 @@ impl ScriptThread {
}
MouseMoveEvent(point) => {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -1980,17 +1990,19 @@ impl ScriptThread {
}
TouchpadPressureEvent(point, pressure, phase) => {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(doc) => doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let doc = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(doc) => doc,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ doc.handle_touchpad_pressure_event(self.js_runtime.rt(), point, pressure, phase);
}
KeyEvent(ch, key, state, modifiers) => {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ document.dispatch_key_event(ch, key, state, modifiers, &self.constellation_chan);
}
}
}
@@ -2000,10 +2012,11 @@ impl ScriptThread {
mouse_event_type: MouseEventType,
button: MouseButton,
point: Point2D<f32>) {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type),
- None => warn!("Message sent to closed pipeline {}.", pipeline_id),
- }
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
+ None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
+ };
+ document.handle_mouse_event(self.js_runtime.rt(), button, point, mouse_event_type);
}
fn handle_touch_event(&self,
@@ -2012,13 +2025,14 @@ impl ScriptThread {
identifier: TouchId,
point: Point2D<f32>)
-> TouchEventResult {
- match self.documents.borrow().find_document(pipeline_id) {
- Some(document) => document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point),
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
+ Some(document) => document,
None => {
warn!("Message sent to closed pipeline {}.", pipeline_id);
- TouchEventResult::Processed(true)
+ return TouchEventResult::Processed(true);
},
- }
+ };
+ document.handle_touch_event(self.js_runtime.rt(), event_type, identifier, point)
}
/// https://html.spec.whatwg.org/multipage/#navigating-across-documents
@@ -2044,7 +2058,7 @@ impl ScriptThread {
}
fn handle_resize_event(&self, pipeline_id: PipelineId, new_size: WindowSizeData, size_type: WindowSizeType) {
- let document = match self.documents.borrow().find_document(pipeline_id) {
+ let document = match { self.documents.borrow().find_document(pipeline_id) } {
Some(document) => document,
None => return warn!("Message sent to closed pipeline {}.", pipeline_id),
};
@@ -2127,7 +2141,7 @@ impl ScriptThread {
}
fn handle_parsing_complete(&self, id: PipelineId) {
- let document = match self.documents.borrow().find_document(id) {
+ let document = match { self.documents.borrow().find_document(id) } {
Some(document) => document,
None => return,
};
@@ -2175,7 +2189,8 @@ impl ScriptThread {
}
fn handle_reload(&self, pipeline_id: PipelineId) {
- if let Some(window) = self.documents.borrow().find_window(pipeline_id) {
+ let window = self.documents.borrow().find_window(pipeline_id);
+ if let Some(window) = window {
window.Location().Reload();
}
}