Skip to main content

bus_queue/
swap_slot.rs

1use std::sync::Arc;
2
3/// Trait required by implementers of syncing primitives.
4pub trait SwapSlot<T> {
5    /// Creates a new Arc around item and stores it,
6    /// dropping the previously held item's Arc.
7    fn store(&self, item: T);
8    /// Returns a clone of the held Arc,
9    /// incrementing the ref count atomically
10    fn load(&self) -> Arc<T>;
11    /// Creates a placeholder without an item.
12    /// Due to the queue's internal implementation
13    /// placeholders are never read, only overwritten,
14    /// but are required because of the bounded constraint.
15    fn none() -> Self;
16}
17#[cfg(test)]
18mod test {
19    // uses the libraries default exported slot
20    use crate::swap_slot::SwapSlot;
21    use crate::Slot;
22    use std::sync::Arc;
23
24    #[test]
25    fn test_swap_slot() {
26        // Initialize slot
27        let item = Slot::none();
28
29        // Store an item into the slot, ref count = 1
30        SwapSlot::store(&item, 1);
31
32        // Load an item from the slot, ref count = 2
33        let arc = SwapSlot::load(&item);
34        assert_eq!(*arc, 1);
35        assert_eq!(Arc::strong_count(&arc), 2);
36
37        // Store another item into the slot overwriting the previous item.
38        // old item ref count drops to 1, new item ref count is 1.
39        SwapSlot::store(&item, 2);
40        assert_eq!(Arc::strong_count(&arc), 1);
41
42        // Load new item from the slot, ref count 2
43        let arc = SwapSlot::load(&item);
44        assert_eq!(*arc, 2);
45        assert_eq!(Arc::strong_count(&arc), 2);
46    }
47}