X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-core%2Fsrc%2Frefs.rs;h=292c8887d4cf376c3413d0faf42e37e10cd10d6c;hb=e64739f87a35f29be0bbbce366876180ba3eb57e;hp=f2b0577866174e1d5910f6062e1b4e9ef23aceaa;hpb=1a967e6bad5f17943b4de0607078eb940ad5adfe;p=nihav.git diff --git a/nihav-core/src/refs.rs b/nihav-core/src/refs.rs index f2b0577..292c888 100644 --- a/nihav-core/src/refs.rs +++ b/nihav-core/src/refs.rs @@ -1,4 +1,5 @@ use std::ops::{Deref, DerefMut}; +use std::convert::AsRef; use std::sync::atomic::*; struct NABufferData { @@ -9,17 +10,15 @@ struct NABufferData { impl NABufferData { fn new(data: T) -> Self { Self { - data: data, + data, refs: AtomicUsize::new(1), } } fn inc_refs(obj: &mut Self) { obj.refs.fetch_add(1, Ordering::SeqCst); } - fn dec_refs(obj: &mut Self) { - if obj.refs.fetch_sub(1, Ordering::SeqCst) == 0 { - std::mem::forget(obj); - } + fn dec_refs(obj: &mut Self) -> bool { + obj.refs.fetch_sub(1, Ordering::SeqCst) == 1 } fn get_num_refs(obj: &Self) -> usize { obj.refs.load(Ordering::Relaxed) @@ -36,6 +35,9 @@ pub struct NABufferRef { ptr: *mut NABufferData, } +unsafe impl Sync for NABufferRef {} +unsafe impl Send for NABufferRef {} + impl NABufferRef { pub fn new(val: T) -> Self { let bdata = NABufferData::new(val); @@ -47,14 +49,17 @@ impl NABufferRef { NABufferData::get_num_refs(self.ptr.as_mut().unwrap()) } } - pub fn as_ref(&self) -> &T { + pub fn as_mut(&mut self) -> Option<&mut T> { unsafe { - NABufferData::get_read_ptr(self.ptr.as_mut().unwrap()) + NABufferData::get_write_ptr(self.ptr.as_mut().unwrap()) } } - pub fn as_mut(&mut self) -> Option<&mut T> { +} + +impl AsRef for NABufferRef { + fn as_ref(&self) -> &T { unsafe { - NABufferData::get_write_ptr(self.ptr.as_mut().unwrap()) + NABufferData::get_read_ptr(self.ptr.as_mut().unwrap()) } } } @@ -80,8 +85,16 @@ impl Clone for NABufferRef { impl Drop for NABufferRef { fn drop(&mut self) { unsafe { - NABufferData::dec_refs(self.ptr.as_mut().unwrap()); + if NABufferData::dec_refs(self.ptr.as_mut().unwrap()) { + let data = Box::from_raw(self.ptr); + std::mem::drop(data); + } } } } +impl Default for NABufferRef { + fn default() -> Self { + Self::new(T::default()) + } +}