1use core::ptr;
2
3use alloc::rc::Weak as RcWeak;
4use alloc::sync::Weak;
5
6use crate::RefCnt;
7
8unsafe impl<T> RefCnt for Weak<T> {
9 type Base = T;
10 fn as_ptr(me: &Self) -> *mut T {
11 if Weak::ptr_eq(&Weak::new(), me) {
12 ptr::null_mut()
13 } else {
14 Weak::as_ptr(me) as *mut T
15 }
16 }
17 fn into_ptr(me: Self) -> *mut T {
18 if Weak::ptr_eq(&Weak::new(), &me) {
19 ptr::null_mut()
20 } else {
21 Weak::into_raw(me) as *mut T
22 }
23 }
24 unsafe fn from_ptr(ptr: *const T) -> Self {
25 if ptr.is_null() {
26 Weak::new()
27 } else {
28 Weak::from_raw(ptr)
29 }
30 }
31}
32
33unsafe impl<T> RefCnt for RcWeak<T> {
34 type Base = T;
35 fn as_ptr(me: &Self) -> *mut T {
36 if RcWeak::ptr_eq(&RcWeak::new(), me) {
37 ptr::null_mut()
38 } else {
39 RcWeak::as_ptr(me) as *mut T
40 }
41 }
42 fn into_ptr(me: Self) -> *mut T {
43 if RcWeak::ptr_eq(&RcWeak::new(), &me) {
44 ptr::null_mut()
45 } else {
46 RcWeak::into_raw(me) as *mut T
47 }
48 }
49 unsafe fn from_ptr(ptr: *const T) -> Self {
50 if ptr.is_null() {
51 RcWeak::new()
52 } else {
53 RcWeak::from_raw(ptr)
54 }
55 }
56}
57
58macro_rules! t {
59 ($name: ident, $strategy: ty) => {
60 #[cfg(test)]
61 mod $name {
62 use alloc::sync::{Arc, Weak};
63
64 use crate::ArcSwapAny;
65
66 #[allow(deprecated)] type ArcSwapWeak<T> = ArcSwapAny<Weak<T>, $strategy>;
68
69 #[test]
71 fn there_and_back() {
72 let data = Arc::new("Hello");
73 let shared = ArcSwapWeak::new(Arc::downgrade(&data));
74 assert_eq!(1, Arc::strong_count(&data));
75 assert_eq!(1, Arc::weak_count(&data));
76 let weak = shared.load();
77 assert_eq!("Hello", *weak.upgrade().unwrap());
78 assert!(Arc::ptr_eq(&data, &weak.upgrade().unwrap()));
79 }
80
81 #[test]
83 fn reset() {
84 let data = Arc::new("Hello");
85 let shared = ArcSwapWeak::new(Arc::downgrade(&data));
86 assert_eq!(1, Arc::strong_count(&data));
87 assert_eq!(1, Arc::weak_count(&data));
88
89 shared.store(Weak::new());
91 assert_eq!(1, Arc::strong_count(&data));
92 assert_eq!(0, Arc::weak_count(&data));
93
94 let weak = shared.load();
95 assert!(weak.upgrade().is_none());
96 }
97
98 #[test]
101 fn destroy() {
102 let data = Arc::new("Hello");
103 let shared = ArcSwapWeak::new(Arc::downgrade(&data));
104
105 drop(data);
106 let weak = shared.load();
107 assert!(weak.upgrade().is_none());
108 }
109 }
110 };
111}
112
113t!(tests_default, crate::DefaultStrategy);
114#[cfg(feature = "internal-test-strategies")]
115t!(
116 tests_full_slots,
117 crate::strategy::test_strategies::FillFastSlots
118);