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
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::sync::atomic::Ordering;
use FillOnceAtomicOption;
pub struct Node<T> {
value: T,
next: FillOnceAtomicOption<Node<T>>,
}
impl<T> Node<T> {
#[inline]
pub fn value(&self) -> &T {
trace!("value() = {:p}", &self.value);
&self.value
}
#[inline]
pub fn new(value: T) -> Self {
trace!("new()");
let next = FillOnceAtomicOption::default();
Self { value, next }
}
#[inline]
pub fn next(&self) -> Option<&Self> {
trace!("next()");
self.next.get_ref(Ordering::SeqCst)
}
#[inline]
pub fn set_next(&self, node: Box<Self>) {
trace!("set_next({:p})", node);
#[allow(unused)]
let ret = self.next.try_store(node, Ordering::SeqCst);
debug_assert!(ret.is_ok());
}
}
impl<T> Drop for Node<T> {
fn drop(&mut self) {
info!("Drop chained nodes");
let mut node = unsafe { self.next.dangle() };
while let Some(mut n) = node {
node = unsafe { n.next.dangle() };
}
debug!("Dropped all chained nodes");
}
}
impl<T: Debug> Debug for Node<T> {
#[inline]
fn fmt(&self, f: &mut Formatter) -> FmtResult {
f.debug_struct("Node")
.field("value", &self.value)
.field("next", &self.next.get_ref(Ordering::SeqCst))
.finish()
}
}