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
2929 /// than once
30+ /// - It must be valid to call `next()` on the `node`, meaning it must be properly initialized
31+ /// for insertion into a stack/linked list
3032 pub unsafe fn push ( & self , node : NonNullPtr < N > ) {
3133 impl_:: push ( self , node) ;
3234 }
@@ -39,10 +41,22 @@ where
3941pub trait Node : Sized {
4042 type Data ;
4143
42- fn next ( & self ) -> & AtomicPtr < Self > ;
44+ /// Returns a reference to the atomic pointer that stores the link to the next `Node`
45+ ///
46+ /// # Safety
47+ ///
48+ /// It must be valid to obtain a reference to the next link pointer, e.g. in the case of
49+ /// `UnionNode`, the `next` field must be properly initialized when calling this function
50+ unsafe fn next ( & self ) -> & AtomicPtr < Self > ;
4351
52+ /// Returns a mutable reference to the atomic pointer that stores the link to the next `Node`
53+ ///
54+ /// # Safety
55+ ///
56+ /// It must be valid to obtain a reference to the next link pointer, e.g. in the case of
57+ /// `UnionNode`, the `next` field must be properly initialized when calling this function
4458 #[ allow( dead_code) ] // used conditionally
45- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > ;
59+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > ;
4660}
4761
4862#[ repr( C ) ]
@@ -51,14 +65,28 @@ pub union UnionNode<T> {
5165 pub data : ManuallyDrop < T > ,
5266}
5367
68+ impl < T > UnionNode < T > {
69+ /// Returns a new `UnionNode` that does not contain data and is not linked to any other nodes.
70+ /// The return value of this function is guaranteed to have the `next` field properly
71+ /// initialized. Use this function if you want to insert a new `UnionNode` into a linked
72+ /// list
73+ pub const fn unlinked ( ) -> Self {
74+ Self {
75+ next : ManuallyDrop :: new ( AtomicPtr :: null ( ) ) ,
76+ }
77+ }
78+ }
79+
5480impl < T > Node for UnionNode < T > {
5581 type Data = T ;
5682
57- fn next ( & self ) -> & AtomicPtr < Self > {
83+ unsafe fn next ( & self ) -> & AtomicPtr < Self > {
84+ // SAFETY: Caller ensures that `self.next` is properly initialized
5885 unsafe { & self . next }
5986 }
6087
61- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
88+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
89+ // SAFETY: Caller ensures that `self.next` is properly initialized
6290 unsafe { & mut self . next }
6391 }
6492}
@@ -71,11 +99,11 @@ pub struct StructNode<T> {
7199impl < T > Node for StructNode < T > {
72100 type Data = T ;
73101
74- fn next ( & self ) -> & AtomicPtr < Self > {
102+ unsafe fn next ( & self ) -> & AtomicPtr < Self > {
75103 & self . next
76104 }
77105
78- fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
106+ unsafe fn next_mut ( & mut self ) -> & mut AtomicPtr < Self > {
79107 & mut self . next
80108 }
81109}
0 commit comments