1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::{
    fmt,
    mem::{replace, uninitialized, ManuallyDrop},
    sync::atomic::{
        AtomicBool,
        Ordering::{self, *},
    },
};

/// A shared removable value. You can only take values from this type (no
/// insertion allowed). No extra allocation is necessary. It may be useful for
/// things like shared `thread::JoinHandle`s.
pub struct Removable<T> {
    item: ManuallyDrop<T>,
    present: AtomicBool,
}

impl<T> Removable<T> {
    /// Creates a removable item with the passed argument as a present value.
    pub fn new(val: T) -> Self {
        Self { item: ManuallyDrop::new(val), present: AtomicBool::new(true) }
    }

    /// Creates a removable item with no present value.
    pub fn empty() -> Self {
        Self {
            // This is safe because we will only read from the item if present
            // is true. Present will only be true if we write to it.
            item: ManuallyDrop::new(unsafe { uninitialized() }),
            present: AtomicBool::new(false),
        }
    }

    /// Replaces the stored value with a given one and returns the old value.
    /// Requires a mutable reference since the type of the value might not be
    /// atomic.
    pub fn replace(&mut self, val: Option<T>) -> Option<T> {
        let present = self.present.get_mut();

        match val {
            Some(val) => {
                if *present {
                    Some(replace(&mut *self.item, val))
                } else {
                    // Safe because we get the pointer from a valid reference
                    // and present will only be false if item is uninitialized.
                    *present = true;
                    unsafe { (&mut *self.item as *mut T).write(val) };
                    None
                }
            },

            None if *present => {
                // Safe because we get the pointer from a valid reference
                // and present will only be false if item is uninitialized.
                *present = false;
                Some(unsafe { (&*self.item as *const T).read() })
            },

            None => None,
        }
    }

    /// Tries to get a mutable reference to the stored value. If the value was
    /// not present, `None` is returned.
    pub fn get_mut(&mut self) -> Option<&mut T> {
        if *self.present.get_mut() {
            Some(&mut *self.item)
        } else {
            None
        }
    }

    /// Tests if the stored value is present. Note that there are no guarantees
    /// that `take` will be successful if this method returns `true` because
    /// some other thread could take the value meanwhile.
    pub fn is_present(&self, ordering: Ordering) -> bool {
        self.present.load(ordering)
    }

    /// Tries to take the value. If no value was present in first place, `None`
    /// is returned. In terms of memory ordering, `AcqRel` should be enough.
    pub fn take(&self, ordering: Ordering) -> Option<T> {
        if self.present.swap(false, ordering) {
            // Safe because if present was true, the memory was initialized. All
            // other reads won't happen because we set present to false.
            Some(unsafe { (&*self.item as *const T).read() })
        } else {
            None
        }
    }
}

impl<T> fmt::Debug for Removable<T> {
    fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
        write!(
            fmtr,
            "Removable {} present: {:?} {}",
            '{',
            self.is_present(Relaxed),
            '}'
        )
    }
}

impl<T> Default for Removable<T> {
    fn default() -> Self {
        Self::empty()
    }
}

impl<T> Drop for Removable<T> {
    fn drop(&mut self) {
        if *self.present.get_mut() {
            // Safe because present will only be true when the memory is
            // initialized. And now we are at drop.
            unsafe { ManuallyDrop::drop(&mut self.item) }
        }
    }
}

impl<T> From<Option<T>> for Removable<T> {
    fn from(opt: Option<T>) -> Self {
        match opt {
            Some(item) => Self::new(item),
            None => Self::empty(),
        }
    }
}

unsafe impl<T> Send for Removable<T> where T: Send {}
unsafe impl<T> Sync for Removable<T> where T: Send {}