From 7c8b1de881730cb3e3bd6c842c021a68fcea5995 Mon Sep 17 00:00:00 2001 From: Clinton Selke Date: Sat, 17 Nov 2018 20:45:30 +1000 Subject: [PATCH] default listen is changed to strong and listen_weak added for the weak version of listen --- src/sodium/cell.rs | 7 +++++++ src/sodium/impl_/cell.rs | 17 ++++++++++++++++- src/sodium/impl_/listener.rs | 16 +++++++++++++--- src/sodium/impl_/sodium_ctx.rs | 17 +++++++++++++++-- src/sodium/impl_/stream.rs | 17 ++++++++++++++++- src/sodium/is_cell.rs | 7 +++++++ src/sodium/is_stream.rs | 7 +++++++ src/sodium/stream.rs | 7 +++++++ 8 files changed, 88 insertions(+), 7 deletions(-) diff --git a/src/sodium/cell.rs b/src/sodium/cell.rs index f12ec71..4f24567 100644 --- a/src/sodium/cell.rs +++ b/src/sodium/cell.rs @@ -91,6 +91,13 @@ impl Cell { ) -> Listener { self.impl_.listen(callback) } + + pub fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self.impl_.listen_weak(callback) + } } impl Clone for Cell { diff --git a/src/sodium/impl_/cell.rs b/src/sodium/impl_/cell.rs index 1dfd1dc..97173e4 100644 --- a/src/sodium/impl_/cell.rs +++ b/src/sodium/impl_/cell.rs @@ -408,6 +408,21 @@ impl Cell { pub fn listen( &self, callback: CALLBACK + ) -> Listener { + self._listen(callback, false) + } + + pub fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self._listen(callback, true) + } + + pub fn _listen( + &self, + callback: CALLBACK, + weak: bool ) -> Listener { let sodium_ctx = self._node().sodium_ctx(); let sodium_ctx = &sodium_ctx; @@ -435,7 +450,7 @@ impl Cell { vec![self._node().clone()], || {}, String::from("Cell::listen_node") - )) + ), weak) } } diff --git a/src/sodium/impl_/listener.rs b/src/sodium/impl_/listener.rs index 2158dd5..df76206 100644 --- a/src/sodium/impl_/listener.rs +++ b/src/sodium/impl_/listener.rs @@ -6,7 +6,8 @@ use sodium::gc::Trace; use std::cell::UnsafeCell; pub struct Listener { - node_op: Gc>> + node_op: Gc>>, + weak: bool } impl Listener { @@ -14,17 +15,26 @@ impl Listener { self.node_op.debug(); } - pub fn new(node: Node) -> Listener { + pub fn new(node: Node, weak: bool) -> Listener { let sodium_ctx = node.sodium_ctx(); let mut gc_ctx = sodium_ctx.gc_ctx(); + if !weak { + sodium_ctx.add_keep_alive(node.clone()); + } Listener { - node_op: gc_ctx.new_gc_with_desc(UnsafeCell::new(Some(node)), String::from("Listener::new")) + node_op: gc_ctx.new_gc_with_desc(UnsafeCell::new(Some(node)), String::from("Listener::new")), + weak } } pub fn unlisten(&self) { + let weak = self.weak; let node_op = unsafe { &mut *(*self.node_op).get() }; if let &mut Some(ref mut node) = node_op { + let sodium_ctx = node.sodium_ctx(); + if !weak { + sodium_ctx.remove_keep_alive(node); + } node.remove_all_dependencies(); } *node_op = None; diff --git a/src/sodium/impl_/sodium_ctx.rs b/src/sodium/impl_/sodium_ctx.rs index c816048..68ac353 100644 --- a/src/sodium/impl_/sodium_ctx.rs +++ b/src/sodium/impl_/sodium_ctx.rs @@ -2,6 +2,7 @@ use sodium::gc::Finalize; use sodium::gc::GcCtx; use sodium::gc::Trace; use sodium::impl_::IsLambda0; +use sodium::impl_::Listener; use sodium::impl_::MemoLazy; use sodium::impl_::Node; use std::cell::UnsafeCell; @@ -28,7 +29,8 @@ pub struct SodiumCtxData { pub resort_required: bool, pub pre_trans: Vec>, pub post_trans: Vec>, - pub node_count: u32 + pub node_count: u32, + pub keep_alive: HashSet } impl SodiumCtx { @@ -43,7 +45,8 @@ impl SodiumCtx { resort_required: false, pre_trans: Vec::new(), post_trans: Vec::new(), - node_count: 0 + node_count: 0, + keep_alive: HashSet::new() })) } } @@ -72,6 +75,16 @@ impl SodiumCtx { id } + pub fn add_keep_alive(&self, node: Node) { + let self_ = unsafe { &mut *(*self.data).get() }; + self_.keep_alive.insert(node); + } + + pub fn remove_keep_alive(&self, node: &Node) { + let self_ = unsafe { &mut *(*self.data).get() }; + self_.keep_alive.remove(node); + } + pub fn inc_node_count(&self) { let self_ = unsafe { &mut *(*self.data).get() }; self_.node_count = self_.node_count + 1; diff --git a/src/sodium/impl_/stream.rs b/src/sodium/impl_/stream.rs index 0a0de98..e68e7ed 100644 --- a/src/sodium/impl_/stream.rs +++ b/src/sodium/impl_/stream.rs @@ -451,6 +451,21 @@ impl Stream { pub fn listen( &self, callback: CALLBACK + ) -> Listener { + self._listen(callback, false) + } + + pub fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self._listen(callback, true) + } + + pub fn _listen( + &self, + callback: CALLBACK, + weak: bool ) -> Listener { let sodium_ctx = self._node().sodium_ctx(); let sodium_ctx = &sodium_ctx; @@ -482,7 +497,7 @@ impl Stream { vec![self._node().clone()], || {}, String::from("Stream::listen_node") - )) + ), weak) } } diff --git a/src/sodium/is_cell.rs b/src/sodium/is_cell.rs index 7c43b5e..87314cd 100644 --- a/src/sodium/is_cell.rs +++ b/src/sodium/is_cell.rs @@ -55,6 +55,13 @@ pub trait IsCell: Sized { ) -> Listener { self.to_cell().listen(callback) } + + fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self.to_cell().listen(callback) + } } impl IsCell for Cell { diff --git a/src/sodium/is_stream.rs b/src/sodium/is_stream.rs index e140e0c..2e3aa6a 100644 --- a/src/sodium/is_stream.rs +++ b/src/sodium/is_stream.rs @@ -117,6 +117,13 @@ pub trait IsStream { ) -> Listener { self.to_stream().listen(callback) } + + fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self.to_stream().listen_weak(callback) + } } impl IsStream for Stream { diff --git a/src/sodium/stream.rs b/src/sodium/stream.rs index b9b90ea..4572f6a 100644 --- a/src/sodium/stream.rs +++ b/src/sodium/stream.rs @@ -133,6 +133,13 @@ impl Stream { ) -> Listener { self.impl_.listen(callback) } + + pub fn listen_weak( + &self, + callback: CALLBACK + ) -> Listener { + self.impl_.listen_weak(callback) + } } impl Clone for Stream {