diff options
-rw-r--r-- | components/layout/construct.rs | 7 | ||||
-rw-r--r-- | components/layout/layout_task.rs | 11 | ||||
-rw-r--r-- | components/layout/util.rs | 6 | ||||
-rw-r--r-- | components/script/dom/node.rs | 47 | ||||
-rw-r--r-- | components/script/layout_interface.rs | 4 |
5 files changed, 35 insertions, 40 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index aa6a50f0545..b2ea8090ea6 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1329,6 +1329,13 @@ impl<'ln> NodeUtils for ThreadSafeLayoutNode<'ln> { let mut layout_data_ref = self.mutate_layout_data(); let layout_data = layout_data_ref.as_mut().expect("no layout data"); + match result { + ConstructionResult::None => { + layout_data.clear(); + } + _ => {} + } + let dst = self.get_construction_result(layout_data); *dst = result; diff --git a/components/layout/layout_task.rs b/components/layout/layout_task.rs index 1b043c3d26b..ca321f23526 100644 --- a/components/layout/layout_task.rs +++ b/components/layout/layout_task.rs @@ -35,7 +35,7 @@ use gfx::paint_task::Msg as PaintMsg; use layout_traits::{LayoutControlMsg, LayoutTaskFactory}; use log; use script::dom::bindings::js::LayoutJS; -use script::dom::node::{LayoutDataRef, Node, NodeTypeId}; +use script::dom::node::{LayoutData, Node, NodeTypeId}; use script::dom::element::ElementTypeId; use script::dom::htmlelement::HTMLElementTypeId; use script::layout_interface::{ContentBoxResponse, ContentBoxesResponse}; @@ -937,11 +937,10 @@ impl LayoutTask { } /// Handles a message to destroy layout data. Layout data must be destroyed on *this* task - /// because it contains local managed pointers. - unsafe fn handle_reap_layout_data(layout_data: LayoutDataRef) { - let mut layout_data_ref = layout_data.borrow_mut(); - let _: Option<LayoutDataWrapper> = mem::transmute( - mem::replace(&mut *layout_data_ref, None)); + /// because the struct type is transmuted to a different type on the script side. + unsafe fn handle_reap_layout_data(layout_data: LayoutData) { + let layout_data_wrapper: LayoutDataWrapper = mem::transmute(layout_data); + layout_data_wrapper.clear(); } /// Returns profiling information which is passed to the time profiler. diff --git a/components/layout/util.rs b/components/layout/util.rs index fca6fabb3ed..8d4d72e7466 100644 --- a/components/layout/util.rs +++ b/components/layout/util.rs @@ -78,6 +78,12 @@ pub struct LayoutDataWrapper { pub data: Box<PrivateLayoutData>, } +impl LayoutDataWrapper { + pub fn clear(&self) { + // TODO: Clear items related to this node, e.g. compositor layers + } +} + #[allow(dead_code)] fn static_assertion(x: Option<LayoutDataWrapper>) { unsafe { diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 18910764188..a7b5e5484d6 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -177,9 +177,7 @@ impl NodeFlags { impl Drop for Node { #[allow(unsafe_blocks)] fn drop(&mut self) { - unsafe { - self.reap_layout_data(); - } + self.layout_data.dispose(); } } @@ -205,6 +203,8 @@ pub struct LayoutData { _data: NonZero<*const ()>, } +unsafe impl Send for LayoutData {} + pub struct LayoutDataRef { pub data_cell: RefCell<Option<LayoutData>>, } @@ -218,18 +218,17 @@ impl LayoutDataRef { } } - /// Returns true if there is layout data present. - #[inline] - pub fn is_present(&self) -> bool { - self.data_cell.borrow().is_some() - } - - /// Take the chan out of the layout data if it is present. - pub fn take_chan(&self) -> Option<LayoutChan> { - let mut layout_data = self.data_cell.borrow_mut(); - match &mut *layout_data { - &mut None => None, - &mut Some(ref mut layout_data) => Some(layout_data.chan.take().unwrap()), + /// Sends layout data, if any, back to the layout task to be destroyed. + pub fn dispose(&self) { + if let Some(mut layout_data) = mem::replace(&mut *self.borrow_mut(), None) { + let layout_chan = layout_data.chan.take(); + match layout_chan { + None => {} + Some(chan) => { + let LayoutChan(chan) = chan; + chan.send(Msg::ReapLayoutData(layout_data)).unwrap() + } + } } } @@ -258,8 +257,6 @@ impl LayoutDataRef { } } -unsafe impl Send for LayoutDataRef {} - /// The different types of nodes. #[derive(Copy, PartialEq, Debug)] #[jstraceable] @@ -302,6 +299,7 @@ impl<'a> PrivateNodeHelpers for JSRef<'a, Node> { for node in self.traverse_preorder() { vtable_for(&node).unbind_from_tree(parent_in_doc); } + self.layout_data.dispose(); } // @@ -1648,21 +1646,6 @@ impl Node { Temporary::from_rooted(copy.r()) } - /// Sends layout data, if any, back to the layout task to be destroyed. - unsafe fn reap_layout_data(&mut self) { - if self.layout_data.is_present() { - let layout_data = mem::replace(&mut self.layout_data, LayoutDataRef::new()); - let layout_chan = layout_data.take_chan(); - match layout_chan { - None => {} - Some(chan) => { - let LayoutChan(chan) = chan; - chan.send(Msg::ReapLayoutData(layout_data)).unwrap() - }, - } - } - } - pub fn collect_text_contents<'a, T: Iterator<Item=JSRef<'a, Node>>>(iterator: T) -> String { let mut content = String::new(); for node in iterator { diff --git a/components/script/layout_interface.rs b/components/script/layout_interface.rs index c82370207cf..5b83c471b73 100644 --- a/components/script/layout_interface.rs +++ b/components/script/layout_interface.rs @@ -6,7 +6,7 @@ //! interface helps reduce coupling between these two components, and enables //! the DOM to be placed in a separate crate from layout. -use dom::node::LayoutDataRef; +use dom::node::LayoutData; use geom::point::Point2D; use geom::rect::Rect; @@ -41,7 +41,7 @@ pub enum Msg { /// Destroys layout data associated with a DOM node. /// /// TODO(pcwalton): Maybe think about batching to avoid message traffic. - ReapLayoutData(LayoutDataRef), + ReapLayoutData(LayoutData), /// Requests that the layout task enter a quiescent state in which no more messages are /// accepted except `ExitMsg`. A response message will be sent on the supplied channel when |