@@ -33,43 +33,43 @@ impl crate::Inner {
33
33
/// Add a new listener to the list.
34
34
///
35
35
/// Does nothing if the list is already registered.
36
- pub ( crate ) fn insert ( & self , listener : & mut Listener ) {
37
- if let Listener :: HasNode ( _ ) | Listener :: Queued ( _ ) = * listener {
36
+ pub ( crate ) fn insert ( & self , listener : & mut Option < Listener > ) {
37
+ if listener . is_some ( ) {
38
38
// Already inserted.
39
39
return ;
40
40
}
41
41
42
42
match self . try_lock ( ) {
43
43
Some ( mut lock) => {
44
44
let key = lock. insert ( State :: Created ) ;
45
- * listener = Listener :: HasNode ( key) ;
45
+ * listener = Some ( Listener :: HasNode ( key) ) ;
46
46
}
47
47
48
48
None => {
49
49
// Push it to the queue.
50
50
let ( node, task_waiting) = Node :: listener ( ) ;
51
51
self . list . queue . push ( node) ;
52
- * listener = Listener :: Queued ( task_waiting) ;
52
+ * listener = Some ( Listener :: Queued ( task_waiting) ) ;
53
53
}
54
54
}
55
55
}
56
56
57
57
/// Remove a listener from the list.
58
- pub ( crate ) fn remove ( & self , listener : & mut Listener , propogate : bool ) -> Option < State > {
59
- let state = match mem :: replace ( listener, Listener :: Discarded ) {
60
- Listener :: HasNode ( key) => {
58
+ pub ( crate ) fn remove ( & self , listener : & mut Option < Listener > , propogate : bool ) -> Option < State > {
59
+ let state = match listener. take ( ) {
60
+ Some ( Listener :: HasNode ( key) ) => {
61
61
match self . try_lock ( ) {
62
62
Some ( mut list) => {
63
63
// Fast path removal.
64
- list. remove ( Listener :: HasNode ( key) , propogate)
64
+ list. remove ( key, propogate)
65
65
}
66
66
67
67
None => {
68
68
// Slow path removal.
69
69
// This is why intrusive lists don't work on no_std.
70
70
let node = Node :: RemoveListener {
71
+ key,
71
72
propagate : propogate,
72
- listener : Listener :: HasNode ( key) ,
73
73
} ;
74
74
75
75
self . list . queue . push ( node) ;
@@ -79,12 +79,12 @@ impl crate::Inner {
79
79
}
80
80
}
81
81
82
- Listener :: Queued ( _) => {
82
+ Some ( Listener :: Queued ( _) ) => {
83
83
// This won't be added after we drop the lock.
84
84
None
85
85
}
86
86
87
- _ => None ,
87
+ None => None ,
88
88
} ;
89
89
90
90
state
@@ -115,11 +115,15 @@ impl crate::Inner {
115
115
///
116
116
/// Returns `true` if the listener was already notified, and `false` otherwise. If the listener
117
117
/// isn't inserted, returns `None`.
118
- pub ( crate ) fn register ( & self , listener : & mut Listener , task : TaskRef < ' _ > ) -> Option < bool > {
118
+ pub ( crate ) fn register (
119
+ & self ,
120
+ listener : & mut Option < Listener > ,
121
+ task : TaskRef < ' _ > ,
122
+ ) -> Option < bool > {
119
123
loop {
120
- match mem :: replace ( listener, Listener :: Discarded ) {
121
- Listener :: HasNode ( key) => {
122
- * listener = Listener :: HasNode ( key) ;
124
+ match listener. take ( ) {
125
+ Some ( Listener :: HasNode ( key) ) => {
126
+ * listener = Some ( Listener :: HasNode ( key) ) ;
123
127
match self . try_lock ( ) {
124
128
Some ( mut guard) => {
125
129
// Fast path registration.
@@ -135,18 +139,18 @@ impl crate::Inner {
135
139
}
136
140
}
137
141
138
- Listener :: Queued ( task_waiting) => {
142
+ Some ( Listener :: Queued ( task_waiting) ) => {
139
143
// Are we done yet?
140
144
match task_waiting. status ( ) {
141
145
Some ( key) => {
142
146
// We're inserted now, adjust state.
143
- * listener = Listener :: HasNode ( key) ;
147
+ * listener = Some ( Listener :: HasNode ( key) ) ;
144
148
}
145
149
146
150
None => {
147
151
// We're still queued, so register the task.
148
152
task_waiting. register ( task. into_task ( ) ) ;
149
- * listener = Listener :: Queued ( task_waiting) ;
153
+ * listener = Some ( Listener :: Queued ( task_waiting) ) ;
150
154
return None ;
151
155
}
152
156
}
@@ -476,12 +480,7 @@ impl ListenerSlab {
476
480
}
477
481
478
482
/// Removes an entry from the list and returns its state.
479
- pub ( crate ) fn remove ( & mut self , listener : Listener , propogate : bool ) -> Option < State > {
480
- let key = match listener {
481
- Listener :: HasNode ( key) => key,
482
- _ => return None ,
483
- } ;
484
-
483
+ pub ( crate ) fn remove ( & mut self , key : NonZeroUsize , propogate : bool ) -> Option < State > {
485
484
let entry = & self . listeners [ key. get ( ) ] ;
486
485
let prev = entry. prev ( ) . get ( ) ;
487
486
let next = entry. next ( ) . get ( ) ;
@@ -569,9 +568,13 @@ impl ListenerSlab {
569
568
///
570
569
/// Returns `true` if the listener was already notified, and `false` otherwise. If the listener
571
570
/// isn't inserted, returns `None`.
572
- pub ( crate ) fn register ( & mut self , listener : & mut Listener , task : TaskRef < ' _ > ) -> Option < bool > {
571
+ pub ( crate ) fn register (
572
+ & mut self ,
573
+ listener : & mut Option < Listener > ,
574
+ task : TaskRef < ' _ > ,
575
+ ) -> Option < bool > {
573
576
let key = match * listener {
574
- Listener :: HasNode ( key) => key,
577
+ Some ( Listener :: HasNode ( key) ) => key,
575
578
_ => return None ,
576
579
} ;
577
580
@@ -581,7 +584,8 @@ impl ListenerSlab {
581
584
match entry. state ( ) . replace ( State :: NotifiedTaken ) {
582
585
State :: Notified ( _) | State :: NotifiedTaken => {
583
586
// The listener was already notified, so we don't need to do anything.
584
- self . remove ( mem:: replace ( listener, Listener :: Discarded ) , false ) ?;
587
+ self . remove ( key, false ) ?;
588
+ * listener = None ;
585
589
Some ( true )
586
590
}
587
591
@@ -609,9 +613,6 @@ pub(crate) enum Listener {
609
613
/// The listener has a node inside of the linked list.
610
614
HasNode ( NonZeroUsize ) ,
611
615
612
- /// The listener has already been notified and has discarded its entry.
613
- Discarded ,
614
-
615
616
/// The listener has an entry in the queue that may or may not have a task waiting.
616
617
Queued ( Arc < TaskWaiting > ) ,
617
618
}
0 commit comments