@@ -8,22 +8,11 @@ use alloc::boxed::Box;
8
8
use core:: ptr:: NonNull ;
9
9
10
10
/// A node in the backup queue.
11
- pub ( crate ) struct Node {
12
- /// The data associated with the node.
13
- data : Option < NodeData > ,
14
- }
15
-
16
- impl From < NodeData > for Node {
17
- fn from ( data : NodeData ) -> Self {
18
- Self { data : Some ( data) }
19
- }
20
- }
21
-
22
- enum NodeData {
11
+ pub ( crate ) enum Node {
23
12
/// This node is requesting to add a listener.
24
13
AddListener {
25
14
/// The pointer to the listener to add.
26
- listener : NonNull < Entry > ,
15
+ listener : Option < DistOwnedListener > ,
27
16
} ,
28
17
29
18
/// This node is notifying a listener.
@@ -42,65 +31,55 @@ enum NodeData {
42
31
Waiting ( Task ) ,
43
32
}
44
33
45
- impl Node {
46
- /// Create a new listener submission entry.
47
- pub ( crate ) fn listener ( ) -> ( Self , NonNull < Entry > ) {
48
- // Allocate an entry on the heap.
49
- let entry = unsafe { NonNull :: new_unchecked ( Box :: into_raw ( Box :: new ( Entry :: new ( ) ) ) ) } ;
50
-
51
- ( NodeData :: AddListener { listener : entry } . into ( ) , entry)
52
- }
34
+ pub ( crate ) struct DistOwnedListener ( NonNull < Entry > ) ;
53
35
54
- /// Create a new notification entry.
55
- pub ( crate ) fn notify ( notify : Notify ) -> Self {
56
- NodeData :: Notify ( notify) . into ( )
36
+ impl DistOwnedListener {
37
+ /// extracts the contained entry pointer from the DOL,
38
+ /// without calling the DOL Drop handler (such that the returned pointer stays valid)
39
+ fn take ( self ) -> NonNull < Entry > {
40
+ ( & * core:: mem:: ManuallyDrop :: new ( self ) ) . 0
57
41
}
42
+ }
58
43
59
- /// Create a new listener removal entry.
60
- pub ( crate ) fn remove_listener ( listener : NonNull < Entry > , propagate : bool ) -> Self {
61
- NodeData :: RemoveListener {
62
- listener,
63
- propagate,
64
- }
65
- . into ( )
44
+ impl Drop for DistOwnedListener {
45
+ fn drop ( & mut self ) {
46
+ drop ( unsafe { Box :: from_raw ( self . 0 . as_ptr ( ) ) } ) ;
66
47
}
48
+ }
67
49
68
- /// Create a new waiting entry.
69
- pub ( crate ) fn waiting ( task : Task ) -> Self {
70
- NodeData :: Waiting ( task) . into ( )
50
+ impl Node {
51
+ pub ( crate ) fn listener ( ) -> ( Self , NonNull < Entry > ) {
52
+ let entry = Box :: into_raw ( Box :: new ( Entry :: new ( ) ) ) ;
53
+ let entry = unsafe { NonNull :: new_unchecked ( entry) } ;
54
+ ( Self :: AddListener { listener : Some ( DistOwnedListener ( entry) ) } , entry)
71
55
}
72
56
73
57
/// Indicate that this node has been enqueued.
74
58
pub ( crate ) fn enqueue ( & self ) {
75
- if let Some ( NodeData :: AddListener { listener } ) = & self . data {
76
- unsafe {
77
- listener. as_ref ( ) . enqueue ( ) ;
78
- }
59
+ if let Node :: AddListener { listener : Some ( entry) } = self {
60
+ unsafe { entry. 0 . as_ref ( ) } . enqueue ( ) ;
79
61
}
80
62
}
81
63
82
64
/// Apply the node to the list.
83
- pub ( crate ) fn apply ( mut self , list : & mut List , inner : & Inner ) -> Option < Task > {
84
- let data = self . data . take ( ) . unwrap ( ) ;
85
-
86
- match data {
87
- NodeData :: AddListener { listener } => {
65
+ pub ( crate ) fn apply ( self , list : & mut List , inner : & Inner ) -> Option < Task > {
66
+ match self {
67
+ Node :: AddListener { mut listener } => {
88
68
// Add the listener to the list.
89
- list. insert ( listener) ;
69
+ let entry = listener. take ( ) . unwrap ( ) . take ( ) ;
70
+ list. insert ( entry) ;
90
71
91
72
// Dequeue the listener.
92
- return unsafe { listener . as_ref ( ) . dequeue ( ) } ;
73
+ return unsafe { entry . as_ref ( ) . dequeue ( ) } ;
93
74
}
94
- NodeData :: Notify ( notify ) => {
75
+ Node :: Notify ( Notify { count , kind } ) => {
95
76
// Notify the listener.
96
- let Notify { count, kind } = notify;
97
-
98
77
match kind {
99
78
NotifyKind :: Notify => list. notify_unnotified ( count) ,
100
79
NotifyKind :: NotifyAdditional => list. notify_additional ( count) ,
101
80
}
102
81
}
103
- NodeData :: RemoveListener {
82
+ Node :: RemoveListener {
104
83
listener,
105
84
propagate,
106
85
} => {
@@ -112,21 +91,11 @@ impl Node {
112
91
list. notify ( 1 , additional) ;
113
92
}
114
93
}
115
- NodeData :: Waiting ( task) => {
94
+ Node :: Waiting ( task) => {
116
95
return Some ( task) ;
117
96
}
118
97
}
119
98
120
99
None
121
100
}
122
101
}
123
-
124
- impl Drop for Node {
125
- fn drop ( & mut self ) {
126
- if let Some ( NodeData :: AddListener { listener } ) = self . data . take ( ) {
127
- unsafe {
128
- drop ( Box :: from_raw ( listener. as_ptr ( ) ) ) ;
129
- }
130
- }
131
- }
132
- }
0 commit comments