@@ -8,13 +8,14 @@ pub trait Notification {
8
8
/// The tag data associated with a notification.
9
9
type Tag ;
10
10
11
- /// Emit a fence to ensure that the notification is visible to the
12
- /// listeners.
11
+ /// Emit a fence to ensure that the notification is visible to the listeners.
13
12
fn fence ( & self ) ;
14
13
15
- /// Get the number of listeners to wake, given the number of listeners
16
- /// that are currently waiting.
17
- fn count ( & self , waiting : usize ) -> usize ;
14
+ /// Whether or not the number of currently waiting listeners should be subtracted from `count()`.
15
+ fn is_additional ( & self ) -> bool ;
16
+
17
+ /// Get the number of listeners to wake.
18
+ fn count ( & self ) -> usize ;
18
19
19
20
/// Get a tag to be associated with a notification.
20
21
///
@@ -42,46 +43,53 @@ impl From<usize> for Notify {
42
43
impl Notification for Notify {
43
44
type Tag = ( ) ;
44
45
46
+ fn is_additional ( & self ) -> bool {
47
+ false
48
+ }
49
+
45
50
fn fence ( & self ) {
46
51
full_fence ( ) ;
47
52
}
48
53
49
- fn count ( & self , waiting : usize ) -> usize {
50
- self . 0 . saturating_sub ( waiting )
54
+ fn count ( & self ) -> usize {
55
+ self . 0
51
56
}
52
57
53
58
fn next_tag ( & mut self ) -> Self :: Tag { }
54
59
}
55
60
56
- /// Notify a given number of listeners .
61
+ /// Make the underlying notification additional .
57
62
#[ derive( Debug , Clone ) ]
58
- pub struct NotifyAdditional ( usize ) ;
63
+ pub struct Additional < N : ? Sized > ( N ) ;
59
64
60
- impl NotifyAdditional {
61
- /// Create a new `NotifyAdditional ` with the given number of listeners to notify .
62
- fn new ( count : usize ) -> Self {
63
- Self ( count )
65
+ impl < N > Additional < N > {
66
+ /// Create a new `Additional ` with the given notification .
67
+ fn new ( inner : N ) -> Self {
68
+ Self ( inner )
64
69
}
65
70
}
66
71
67
- impl From < usize > for NotifyAdditional {
68
- fn from ( count : usize ) -> Self {
69
- Self :: new ( count )
70
- }
71
- }
72
+ impl < N > Notification for Additional < N >
73
+ where
74
+ N : Notification + ? Sized ,
75
+ {
76
+ type Tag = N :: Tag ;
72
77
73
- impl Notification for NotifyAdditional {
74
- type Tag = ( ) ;
78
+ fn is_additional ( & self ) -> bool {
79
+ true
80
+ }
75
81
76
82
fn fence ( & self ) {
77
- full_fence ( ) ;
83
+ self . 0 . fence ( ) ;
78
84
}
79
85
80
- fn count ( & self , _waiting : usize ) -> usize {
81
- self . 0
86
+ fn count ( & self ) -> usize {
87
+ self . 0 . count ( )
82
88
}
83
89
84
- fn next_tag ( & mut self ) -> Self :: Tag { }
90
+ fn next_tag ( & mut self ) -> Self :: Tag {
91
+ self . 0 . next_tag ( )
92
+ }
85
93
}
86
94
87
95
/// Don't emit a fence for this notification.
@@ -101,12 +109,16 @@ where
101
109
{
102
110
type Tag = N :: Tag ;
103
111
112
+ fn is_additional ( & self ) -> bool {
113
+ self . 0 . is_additional ( )
114
+ }
115
+
104
116
fn fence ( & self ) {
105
117
// Don't emit a fence.
106
118
}
107
119
108
- fn count ( & self , waiting : usize ) -> usize {
109
- self . 0 . count ( waiting )
120
+ fn count ( & self ) -> usize {
121
+ self . 0 . count ( )
110
122
}
111
123
112
124
fn next_tag ( & mut self ) -> Self :: Tag {
@@ -138,12 +150,16 @@ where
138
150
{
139
151
type Tag = T ;
140
152
153
+ fn is_additional ( & self ) -> bool {
154
+ self . inner . is_additional ( )
155
+ }
156
+
141
157
fn fence ( & self ) {
142
158
self . inner . fence ( ) ;
143
159
}
144
160
145
- fn count ( & self , waiting : usize ) -> usize {
146
- self . inner . count ( waiting )
161
+ fn count ( & self ) -> usize {
162
+ self . inner . count ( )
147
163
}
148
164
149
165
fn next_tag ( & mut self ) -> Self :: Tag {
@@ -188,19 +204,58 @@ where
188
204
{
189
205
type Tag = T ;
190
206
207
+ fn is_additional ( & self ) -> bool {
208
+ self . inner . is_additional ( )
209
+ }
210
+
191
211
fn fence ( & self ) {
192
212
self . inner . fence ( ) ;
193
213
}
194
214
195
- fn count ( & self , waiting : usize ) -> usize {
196
- self . inner . count ( waiting )
215
+ fn count ( & self ) -> usize {
216
+ self . inner . count ( )
197
217
}
198
218
199
219
fn next_tag ( & mut self ) -> Self :: Tag {
200
220
( self . tag ) ( )
201
221
}
202
222
}
203
223
224
+ /// A single notification.
225
+ pub ( crate ) struct SingleNotify < T > {
226
+ additional : bool ,
227
+ tag : Option < T > ,
228
+ }
229
+
230
+ impl < T > SingleNotify < T > {
231
+ pub ( crate ) fn new ( additional : bool , tag : T ) -> Self {
232
+ Self {
233
+ additional,
234
+ tag : Some ( tag) ,
235
+ }
236
+ }
237
+ }
238
+
239
+ impl < T > Notification for SingleNotify < T > {
240
+ type Tag = T ;
241
+
242
+ fn is_additional ( & self ) -> bool {
243
+ self . additional
244
+ }
245
+
246
+ fn fence ( & self ) {
247
+ // Don't emit a fence.
248
+ }
249
+
250
+ fn count ( & self ) -> usize {
251
+ 1
252
+ }
253
+
254
+ fn next_tag ( & mut self ) -> Self :: Tag {
255
+ self . tag . take ( ) . unwrap ( )
256
+ }
257
+ }
258
+
204
259
/// A value that can be converted into a [`Notification`].
205
260
pub trait IntoNotification {
206
261
/// The tag data associated with a notification.
@@ -213,11 +268,11 @@ pub trait IntoNotification {
213
268
fn into_notification ( self ) -> Self :: Notify ;
214
269
215
270
/// Convert this value into an additional notification.
216
- fn additional ( self ) -> NotifyAdditional
271
+ fn additional ( self ) -> Additional < Self :: Notify >
217
272
where
218
- Self : Sized + IntoNotification < Notify = Notify > ,
273
+ Self : Sized ,
219
274
{
220
- NotifyAdditional :: new ( self . into_notification ( ) . count ( 0 ) )
275
+ Additional :: new ( self . into_notification ( ) )
221
276
}
222
277
223
278
/// Don't emit a fence for this notification.
0 commit comments