arc_swap_simple/
lib.rs

1use std::sync::{atomic::{AtomicPtr, Ordering}, Arc, RwLock};
2
3#[derive(Debug)]
4struct Holder<T>{
5    ptr: AtomicPtr<T>,
6}
7#[derive(Debug)]
8pub struct AtomicSwap<T> {
9    holder: Arc<Holder<T>>,
10}
11
12impl<T> Clone for AtomicSwap<T> {
13    fn clone(&self) -> Self {
14        Self { holder: self.holder.clone() }
15    }
16}
17
18impl<T> AtomicSwap<T> {
19    pub fn from_value(v: T) -> Self{
20        let ptr = Arc::into_raw(Arc::new(v)) as * mut _;
21        AtomicSwap { holder: Arc::new(Holder{ptr: AtomicPtr::new(ptr)})}
22    }
23    
24    pub fn load(&self) -> Arc<T> {
25        let ptr = self.holder.as_ref().ptr.load(Ordering::Acquire);
26        let v = unsafe {Arc::from_raw(ptr)};
27        let v2 = v.clone();
28        assert_eq!(ptr, Arc::into_raw(v) as * mut _);
29        v2
30    }
31    
32    pub fn swap(&self, v: T) -> Arc<T> {
33        let new_ptr = Arc::into_raw(Arc::new(v)) as * mut _;
34        let ptr = self.holder.as_ref().ptr.swap(new_ptr, Ordering::AcqRel);
35        let v = unsafe {Arc::from_raw(ptr)};
36        v
37    }
38}
39
40impl<T> Drop for Holder<T> {
41    fn drop(&mut self) {
42        let _arc = unsafe {Arc::from_raw(self.ptr.load(Ordering::Acquire))};
43    }
44}
45#[derive(Debug)]
46pub struct V{
47    pub v: u32
48}
49impl Drop for V{
50    fn drop(&mut self) {
51        println!("drop V: {:?}", self);
52    }
53}
54#[inline(never)]
55pub fn load_test2(v: &Arc<RwLock<V>>) -> u32{
56    v.read().unwrap().v
57}
58
59#[cfg(test)]
60mod test {
61    use std::time::Duration;
62
63    use super::*;
64    #[test]
65    fn multiple_threads(){
66        let v = AtomicSwap::from_value(V{v: 3});
67        let v2 = v.clone();
68        let t1 = std::thread::spawn(move || {
69            println!("t1: {:?}", v2.load());
70            std::thread::sleep(Duration::from_millis(100));
71            println!("t1: {:?}", v2.load());
72        });
73        std::thread::sleep(Duration::from_millis(50));
74        v.swap(V{v: 10});
75        t1.join().unwrap();
76    }
77}