aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--components/layout/construct.rs7
-rw-r--r--components/layout/layout_task.rs11
-rw-r--r--components/layout/util.rs6
-rw-r--r--components/script/dom/node.rs47
-rw-r--r--components/script/layout_interface.rs4
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