2626 /// # Safety
2727 /// - `node` must be a valid pointer
2828 /// - aliasing rules must be enforced by the caller. e.g, the same `node` may not be pushed more than once
29+ /// - It must be valid to call `next()` on the `node`, meaning it must be properly initialized for insertion
30+ /// into a stack/linked list
2931 pub unsafe fn push ( & self , node : NonNullPtr < N > ) {
3032 impl_:: push ( self , node) ;
3133 }
@@ -38,10 +40,22 @@ where
3840pub trait Node : Sized {
3941 type Data ;
4042
41- fn next ( & self ) -> & AtomicPtr < Self > ;
43+ /// Returns a reference to the atomic pointer that stores the link to the next `Node`
44+ ///
45+ /// # Safety
46+ ///
47+ /// It must be valid to obtain a reference to the next link pointer, e.g. in the case of
48+ /// `UnionNode`, the `next` field must be properly initialized when calling this function
49+ unsafe fn next ( & self ) -> & AtomicPtr < Self > ;
4250
51+ /// Returns a mutable reference to the atomic pointer that stores the link to the next `Node`
52+ ///
53+ /// # Safety
54+ ///
55+ /// It must be valid to obtain a reference to the next link pointer, e.g. in the case of
56+ /// `UnionNode`, the `next` field must be properly initialized when calling this function
4357 #[ allow( dead_code) ] // used conditionally
44- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > ;
58+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > ;
4559}
4660
4761#[ repr( C ) ]
@@ -50,14 +64,27 @@ pub union UnionNode<T> {
5064 pub data : ManuallyDrop < T > ,
5165}
5266
67+ impl < T > UnionNode < T > {
68+ /// Returns a new `UnionNode` that does not contain data and is not linked to any other nodes.
69+ /// The return value of this function is guaranteed to have the `next` field properly initialized.
70+ /// Use this function if you want to insert a new `UnionNode` into a linked list
71+ pub const fn unlinked ( ) -> Self {
72+ Self {
73+ next : ManuallyDrop :: new ( AtomicPtr :: null ( ) ) ,
74+ }
75+ }
76+ }
77+
5378impl < T > Node for UnionNode < T > {
5479 type Data = T ;
5580
56- fn next ( & self ) -> & AtomicPtr < Self > {
81+ unsafe fn next ( & self ) -> & AtomicPtr < Self > {
82+ // SAFETY: Caller ensures that `self.next` is properly initialized
5783 unsafe { & self . next }
5884 }
5985
60- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
86+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
87+ // SAFETY: Caller ensures that `self.next` is properly initialized
6188 unsafe { & mut self . next }
6289 }
6390}
@@ -70,11 +97,11 @@ pub struct StructNode<T> {
7097impl < T > Node for StructNode < T > {
7198 type Data = T ;
7299
73- fn next ( & self ) -> & AtomicPtr < Self > {
100+ unsafe fn next ( & self ) -> & AtomicPtr < Self > {
74101 & self . next
75102 }
76103
77- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
104+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
78105 & mut self . next
79106 }
80107}
0 commit comments