aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/weakref.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/weakref.rs')
-rw-r--r--components/script/dom/bindings/weakref.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/components/script/dom/bindings/weakref.rs b/components/script/dom/bindings/weakref.rs
index e4e5f00103f..abb1e07bc08 100644
--- a/components/script/dom/bindings/weakref.rs
+++ b/components/script/dom/bindings/weakref.rs
@@ -11,6 +11,7 @@
//! slot. When all associated `WeakRef` values are dropped, the
//! `WeakBox` itself is dropped too.
+use dom::bindings::cell::DomRefCell;
use dom::bindings::reflector::DomObject;
use dom::bindings::root::DomRoot;
use dom::bindings::trace::JSTraceable;
@@ -286,3 +287,34 @@ impl<'a, T: WeakReferenceable + 'a> Drop for WeakRefEntry<'a, T> {
*self.index += 1;
}
}
+
+#[derive(MallocSizeOf)]
+pub struct DOMTracker<T: WeakReferenceable> {
+ dom_objects: DomRefCell<WeakRefVec<T>>
+}
+
+impl<T: WeakReferenceable> DOMTracker<T> {
+ pub fn new() -> Self {
+ Self {
+ dom_objects: DomRefCell::new(WeakRefVec::new())
+ }
+ }
+
+ pub fn track(&self, dom_object: &T) {
+ self.dom_objects.borrow_mut().push(WeakRef::new(dom_object));
+ }
+
+ pub fn for_each<F: FnMut(DomRoot<T>)>(&self, mut f: F) {
+ self.dom_objects.borrow_mut().update(|weak_ref| {
+ let root = weak_ref.root().unwrap();
+ f(root);
+ });
+ }
+}
+
+#[allow(unsafe_code)]
+unsafe impl<T: WeakReferenceable> JSTraceable for DOMTracker<T> {
+ unsafe fn trace(&self, _: *mut JSTracer) {
+ self.dom_objects.borrow_mut().retain_alive();
+ }
+}