diff options
author | Ms2ger <Ms2ger@gmail.com> | 2015-11-06 11:37:22 +0100 |
---|---|---|
committer | Ms2ger <Ms2ger@gmail.com> | 2015-11-09 09:03:52 +0100 |
commit | 3f4c734cf4d7c8b54a2eaf190f8550b8d1a80a0d (patch) | |
tree | cfb9cfc2588f65c9d04aeb918eaf0226e84fbf57 /components/layout/layout_task.rs | |
parent | b8d8505463fcb82a3017057ef1fc50f378090b5f (diff) | |
download | servo-3f4c734cf4d7c8b54a2eaf190f8550b8d1a80a0d.tar.gz servo-3f4c734cf4d7c8b54a2eaf190f8550b8d1a80a0d.zip |
Introduce a RwData struct.
Diffstat (limited to 'components/layout/layout_task.rs')
-rw-r--r-- | components/layout/layout_task.rs | 160 |
1 files changed, 78 insertions, 82 deletions
diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index c36a45b8a7d..07b84a3505c 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -311,6 +311,36 @@ impl<'a> DerefMut for RWGuard<'a> { } } +struct RwData<'a, 'b: 'a> { + rw_data: &'b Arc<Mutex<LayoutTaskData>>, + possibly_locked_rw_data: &'a mut Option<MutexGuard<'b, LayoutTaskData>>, +} + +impl<'a, 'b: 'a> RwData<'a, 'b> { + /// If no reflow has happened yet, this will just return the lock in + /// `possibly_locked_rw_data`. Otherwise, it will acquire the `rw_data` lock. + /// + /// If you do not wish RPCs to remain blocked, just drop the `RWGuard` + /// returned from this function. If you _do_ wish for them to remain blocked, + /// use `block`. + fn lock(&mut self) -> RWGuard<'b> { + match self.possibly_locked_rw_data.take() { + None => RWGuard::Used(self.rw_data.lock().unwrap()), + Some(x) => RWGuard::Held(x), + } + } + + /// If no reflow has ever been triggered, this will keep the lock, locked + /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will + /// be unlocked. + fn block(&mut self, rw_data: RWGuard<'b>) { + match rw_data { + RWGuard::Used(x) => drop(x), + RWGuard::Held(x) => *self.possibly_locked_rw_data = Some(x), + } + } +} + fn add_font_face_rules(stylesheet: &Stylesheet, device: &Device, font_cache_task: &FontCacheTask, @@ -432,8 +462,13 @@ impl LayoutTask { /// Starts listening on the port. fn start(self) { - let mut possibly_locked_rw_data = Some((*self.rw_data).lock().unwrap()); - while self.handle_request(&mut possibly_locked_rw_data) { + let rw_data = self.rw_data.clone(); + let mut possibly_locked_rw_data = Some(rw_data.lock().unwrap()); + let mut rw_data = RwData { + rw_data: &rw_data, + possibly_locked_rw_data: &mut possibly_locked_rw_data, + }; + while self.handle_request(&mut rw_data) { // Loop indefinitely. } } @@ -463,9 +498,7 @@ impl LayoutTask { } /// Receives and dispatches messages from the script and constellation tasks - fn handle_request<'a>(&'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) - -> bool { + fn handle_request<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { enum Request { FromPipeline(LayoutControlMsg), FromScript(Msg), @@ -521,7 +554,7 @@ impl LayoutTask { self.repaint(possibly_locked_rw_data) }, Request::FromFontCache => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); rw_data.outstanding_web_fonts.fetch_sub(1, Ordering::SeqCst); font_context::invalidate_font_caches(); self.script_chan.send(ConstellationControlMsg::WebFontLoaded(self.id)).unwrap(); @@ -530,40 +563,13 @@ impl LayoutTask { } } - /// If no reflow has happened yet, this will just return the lock in - /// `possibly_locked_rw_data`. Otherwise, it will acquire the `rw_data` lock. - /// - /// If you do not wish RPCs to remain blocked, just drop the `RWGuard` - /// returned from this function. If you _do_ wish for them to remain blocked, - /// use `return_rw_data`. - fn lock_rw_data<'a>(&'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) - -> RWGuard<'a> { - match possibly_locked_rw_data.take() { - None => RWGuard::Used((*self.rw_data).lock().unwrap()), - Some(x) => RWGuard::Held(x), - } - } - - /// If no reflow has ever been triggered, this will keep the lock, locked - /// (and saved in `possibly_locked_rw_data`). If it has been, the lock will - /// be unlocked. - fn return_rw_data<'a>(possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>, - rw_data: RWGuard<'a>) { - match rw_data { - RWGuard::Used(x) => drop(x), - RWGuard::Held(x) => *possibly_locked_rw_data = Some(x), - } - } - /// Repaint the scene, without performing style matching. This is typically /// used when an image arrives asynchronously and triggers a relayout and /// repaint. /// TODO: In the future we could detect if the image size hasn't changed /// since last time and avoid performing a complete layout pass. - fn repaint<'a>(&'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) -> bool { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn repaint<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) -> bool { + let mut rw_data = possibly_locked_rw_data.lock(); let reflow_info = Reflow { goal: ReflowGoal::ForDisplay, @@ -584,11 +590,10 @@ impl LayoutTask { } /// Receives and dispatches messages from other tasks. - fn handle_request_helper<'a>(&'a self, - request: Msg, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, - LayoutTaskData>>) - -> bool { + fn handle_request_helper<'a, 'b>(&self, + request: Msg, + possibly_locked_rw_data: &mut RwData<'a, 'b>) + -> bool { match request { Msg::AddStylesheet(style_info) => { self.handle_add_stylesheet(style_info, possibly_locked_rw_data) @@ -620,11 +625,11 @@ impl LayoutTask { self.collect_reports(reports_chan, possibly_locked_rw_data); }, Msg::GetCurrentEpoch(sender) => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); sender.send(rw_data.epoch).unwrap(); }, Msg::GetWebFontLoadState(sender) => { - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); let outstanding_web_fonts = rw_data.outstanding_web_fonts.load(Ordering::SeqCst); sender.send(outstanding_web_fonts != 0).unwrap(); }, @@ -645,13 +650,13 @@ impl LayoutTask { true } - fn collect_reports<'a>(&'a self, - reports_chan: ReportsChan, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { + fn collect_reports<'a, 'b>(&self, + reports_chan: ReportsChan, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { let mut reports = vec![]; // FIXME(njn): Just measuring the display tree for now. - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); let stacking_context = rw_data.stacking_context.as_ref(); reports.push(Report { path: path![format!("url({})", self.url), "layout-task", "display-list"], @@ -704,9 +709,9 @@ impl LayoutTask { /// Enters a quiescent state in which no new messages will be processed until an `ExitNow` is /// received. A pong is immediately sent on the given response channel. - fn prepare_to_exit<'a>(&'a self, - response_chan: Sender<()>, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { + fn prepare_to_exit<'a, 'b>(&self, + response_chan: Sender<()>, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { response_chan.send(()).unwrap(); loop { match self.port.recv().unwrap() { @@ -732,14 +737,13 @@ impl LayoutTask { /// Shuts down the layout task now. If there are any DOM nodes left, layout will now (safely) /// crash. - fn exit_now<'a>(&'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { + fn exit_now<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + let mut rw_data = possibly_locked_rw_data.lock(); if let Some(ref mut traversal) = (&mut *rw_data).parallel_traversal { traversal.shutdown() } - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } let (response_chan, response_port) = ipc::channel().unwrap(); @@ -747,14 +751,13 @@ impl LayoutTask { response_port.recv().unwrap() } - fn handle_add_stylesheet<'a>(&'a self, - stylesheet: Arc<Stylesheet>, - possibly_locked_rw_data: - &mut Option<MutexGuard<'a, LayoutTaskData>>) { + fn handle_add_stylesheet<'a, 'b>(&self, + stylesheet: Arc<Stylesheet>, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { // Find all font-face rules and notify the font cache of them. // GWTODO: Need to handle unloading web fonts. - let rw_data = self.lock_rw_data(possibly_locked_rw_data); + let rw_data = possibly_locked_rw_data.lock(); if stylesheet.is_effective_for_device(&rw_data.stylist.device) { add_font_face_rules(&*stylesheet, &rw_data.stylist.device, @@ -763,16 +766,14 @@ impl LayoutTask { &rw_data.outstanding_web_fonts); } - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } /// Sets quirks mode for the document, causing the quirks mode stylesheet to be used. - fn handle_set_quirks_mode<'a>(&'a self, - possibly_locked_rw_data: - &mut Option<MutexGuard<'a, LayoutTaskData>>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn handle_set_quirks_mode<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); rw_data.stylist.set_quirks_mode(true); - LayoutTask::return_rw_data(possibly_locked_rw_data, rw_data); + possibly_locked_rw_data.block(rw_data); } fn try_get_layout_root(&self, node: LayoutNode) -> Option<FlowRef> { @@ -1084,10 +1085,9 @@ impl LayoutTask { } /// The high-level routine that performs layout tasks. - fn handle_reflow<'a>(&'a self, - data: &ScriptReflow, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { - + fn handle_reflow<'a, 'b>(&self, + data: &ScriptReflow, + possibly_locked_rw_data: &mut RwData<'a, 'b>) { // Make sure that every return path from this method joins the script task, // otherwise the script task will panic. struct AutoJoinScriptTask<'a> { data: &'a ScriptReflow }; @@ -1110,7 +1110,7 @@ impl LayoutTask { node.dump(); } - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + let mut rw_data = possibly_locked_rw_data.lock(); let stylesheets: Vec<&Stylesheet> = data.document_stylesheets.iter().map(|entry| &**entry) .collect(); let stylesheets_changed = data.stylesheets_changed; @@ -1232,11 +1232,11 @@ impl LayoutTask { } } - fn set_visible_rects<'a>(&'a self, - new_visible_rects: Vec<(LayerId, Rect<Au>)>, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) - -> bool { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn set_visible_rects<'a, 'b>(&self, + new_visible_rects: Vec<(LayerId, Rect<Au>)>, + possibly_locked_rw_data: &mut RwData<'a, 'b>) + -> bool { + let mut rw_data = possibly_locked_rw_data.lock(); // First, determine if we need to regenerate the display lists. This will happen if the // layers have moved more than `DISPLAY_PORT_THRESHOLD_SIZE_FACTOR` away from their last @@ -1289,10 +1289,8 @@ impl LayoutTask { true } - fn tick_all_animations<'a>(&'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, - LayoutTaskData>>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn tick_all_animations<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); animation::tick_all_animations(self, &mut rw_data) } @@ -1324,10 +1322,8 @@ impl LayoutTask { &mut layout_context); } - pub fn reflow_with_newly_loaded_web_font<'a>( - &'a self, - possibly_locked_rw_data: &mut Option<MutexGuard<'a, LayoutTaskData>>) { - let mut rw_data = self.lock_rw_data(possibly_locked_rw_data); + fn reflow_with_newly_loaded_web_font<'a, 'b>(&self, possibly_locked_rw_data: &mut RwData<'a, 'b>) { + let mut rw_data = possibly_locked_rw_data.lock(); font_context::invalidate_font_caches(); let reflow_info = Reflow { |