I basically have this situation:
use std::sync::Arc;
use std::sync::atomic::AtomicPtr;
struct Foo {
value : Arc<AtomicPtr<String>>
}
struct Bar {
value : Arc<AtomicPtr<String>>
}
fn main() {
let data = Box::new(String::from("abc"));
let foo = Foo { value : Arc::new(AtomicPtr::new(Box::into_raw(data))) };
let bar = Bar { value : foo.value.clone() };
}
First I'm assuming this code would leak the string "abc". Is there an easy way to free the memory?
My first thought was to implement Drop for both structures and use Arc::try_unwrap() but that would move the Arc value out of the structure, so the compiler complains. Another option would be in the Drop Methods to use Arc::strong_count() == 1 and then take the string out and move in a ptr::null_mut(), however Arc::strong_count() is unstable and might be removed in the future.
The only way I can see to do it is add a 3rd class that actually holds the atomic pointer and the other two classes use Arc to reference that, ie:
struct War {
value : AtomicPtr<String>
}
impl Drop for War {
fn drop(&mut self) {
unsafe {
Box::from_raw(self.value.load(Ordering::Acquire));
}
self.value.store(ptr::null_mut(), Ordering::Relaxed);
}
}
I guess my only qualm about this is that it feels like there ALWAYS needs to be this third class if AtomicPtr is pointing to something other than a static values. Which makes me think I'm missing something.