Guest User

Untitled

a guest
May 24th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.19 KB | None | 0 0
  1. use std::collections::HashMap;
  2. use std::marker::PhantomData;
  3. use std::mem;
  4. use std::sync::{Arc, Weak};
  5. use std::sync::atomic::{AtomicUsize, Ordering};
  6.  
  7. struct WeakCell<T>(AtomicUsize, PhantomData<Weak<T>>);
  8.  
  9. impl<T> WeakCell<T> {
  10. /// Creates a new `WeakCell`.
  11. pub fn new(t: Weak<T>) -> WeakCell<T> {
  12. WeakCell(AtomicUsize::new(unsafe { mem::transmute(t) }), PhantomData)
  13. }
  14.  
  15. fn take(&self) -> Weak<T> {
  16. loop {
  17. match self.0.swap(0, Ordering::Acquire) {
  18. 0 => {},
  19. n => return unsafe { mem::transmute(n) },
  20. }
  21. }
  22. }
  23.  
  24. fn put(&self, t: Weak<T>) {
  25. debug_assert_eq!(self.0.load(Ordering::SeqCst), 0);
  26. self.0
  27. .store(unsafe { mem::transmute(t) }, Ordering::Release);
  28. }
  29.  
  30. /// Stores a new value in the `WeakCell`, returning the previous
  31. /// value.
  32. pub fn set(&self, t: Weak<T>) -> Weak<T> {
  33. let old = self.take();
  34. self.put(t);
  35. old
  36. }
  37.  
  38. /// Returns a copy of the value stored by the `WeakCell`.
  39. pub fn get(&self) -> Weak<T> {
  40. let t = self.take();
  41. // NB: correctness here depends on Weak's clone impl not panicking
  42. let out = t.clone();
  43. self.put(t);
  44. out
  45. }
  46. }
  47.  
  48. impl<T> Default for WeakCell<T> {
  49. fn default() -> Self { WeakCell(AtomicUsize::new(0), PhantomData) }
  50. }
  51.  
  52. impl<T> Drop for WeakCell<T> {
  53. fn drop(&mut self) { self.take(); }
  54. }
  55.  
  56. #[derive(Default)]
  57. struct A {
  58. map: HashMap<u32, Vec<B>>,
  59. }
  60.  
  61. struct B {
  62. weak: WeakCell<A>,
  63. }
  64.  
  65. impl A {
  66. pub fn new(map: HashMap<u32, Vec<B>>) -> Arc<A> {
  67. let mut a = Arc::new(A { map });
  68. let copy = a.clone();
  69. for (_, bs) in &mut Arc::get_mut(&mut a).unwrap().map {
  70. for b in bs {
  71. b.weak.set(Arc::downgrade(&copy));
  72. }
  73. }
  74. a
  75. }
  76. }
  77.  
  78. impl B {
  79. pub fn new(a: &Arc<A>) -> B { B { weak: WeakCell::new(Arc::downgrade(a)), } }
  80. }
  81.  
  82. fn main() {
  83. let dummy = Arc::new(A::default());
  84.  
  85. let (b1, b2, b3) = (B::new(&dummy), B::new(&dummy), B::new(&dummy));
  86.  
  87. let mut map = HashMap::new();
  88. map.insert(5, vec![b1, b2]);
  89. map.insert(10, vec![b3]);
  90.  
  91. let _a = A::new(map);
  92.  
  93. // Do something!
  94. }
Add Comment
Please, Sign In to add comment