@@ -58,21 +58,15 @@ impl<T> BufferedEventManager<T> {
58
58
///
59
59
/// When the value given in timeout does not fit within an `i32` e.g.
60
60
/// `timeout.map(|u| i32::try_from(u).unwrap())`.
61
- pub fn wait ( & mut self , timeout : Option < u32 > ) -> Result < & [ T ] , i32 > {
61
+ pub fn wait ( & mut self , timeout : Option < u32 > ) -> Result < Iter < ' _ , T > , i32 > {
62
62
// SAFETY: `EventManager::wait` initializes N element from the start of the slice and only
63
63
// accesses these, thus it will never access uninitialized memory, making this safe.
64
64
unsafe {
65
65
self . buffer . set_len ( self . buffer . capacity ( ) ) ;
66
66
self . output_buffer . set_len ( self . output_buffer . capacity ( ) ) ;
67
67
}
68
- let n = self
69
- . event_manager
70
- . wait ( timeout, & mut self . buffer , & mut self . output_buffer ) ?;
71
- unsafe {
72
- Ok ( self
73
- . output_buffer
74
- . get_unchecked ( ..usize:: try_from ( n) . unwrap_unchecked ( ) ) )
75
- }
68
+ self . event_manager
69
+ . wait ( timeout, & mut self . buffer , & mut self . output_buffer )
76
70
}
77
71
78
72
/// Creates new event manager.
@@ -123,6 +117,62 @@ impl<T> std::fmt::Debug for EventManager<T> {
123
117
}
124
118
}
125
119
120
+ #[ derive( Debug ) ]
121
+ pub struct Iter < ' a , T > {
122
+ event_manager : & ' a mut EventManager < T > ,
123
+ buffer : & ' a [ libc:: epoll_event ] ,
124
+ output_buffer : & ' a mut [ T ] ,
125
+ index : usize ,
126
+ }
127
+ impl < ' a , T > Iter < ' a , T > {
128
+ /// Returns a mutable slice of all the items previously returned by [`Iter::next`].
129
+ pub fn as_mut_slice ( & ' a mut self ) -> & ' a mut [ T ] {
130
+ & mut self . output_buffer [ ..self . index ]
131
+ }
132
+ /// Returns a slice of all the items previously returned by [`Iter::next`].
133
+ pub fn as_slice ( & ' a self ) -> & ' a [ T ] {
134
+ & self . output_buffer [ ..self . index ]
135
+ }
136
+ }
137
+ impl < ' a , T > Iterator for Iter < ' a , T > {
138
+ type Item = & ' a mut T ;
139
+ fn next ( & mut self ) -> Option < Self :: Item > {
140
+ debug_assert_eq ! ( self . buffer. len( ) , self . output_buffer. len( ) ) ;
141
+
142
+ if self . index >= self . buffer . len ( ) {
143
+ return None ;
144
+ }
145
+ unsafe {
146
+ let event = self . buffer . get_unchecked ( self . index ) ;
147
+ // For all events which can fire there exists an entry within `self.events` thus
148
+ // it is safe to unwrap here.
149
+ let f: * const dyn Fn ( & mut EventManager < T > , EventSet ) -> T = self
150
+ . event_manager
151
+ . events
152
+ . get ( & i32:: try_from ( event. u64 ) . unwrap_unchecked ( ) )
153
+ . unwrap_unchecked ( ) ;
154
+ self . output_buffer [ self . index ] = ( * f) (
155
+ self . event_manager ,
156
+ EventSet :: from_bits_unchecked ( event. events ) ,
157
+ ) ;
158
+
159
+ // SAFETY: This is always safe. This is required as the current standard library trait
160
+ // doesn't support lending iteraor semantics.
161
+ let temp = Some ( std:: mem:: transmute ( & mut self . output_buffer [ self . index ] ) ) ;
162
+
163
+ self . index += 1 ;
164
+
165
+ temp
166
+ }
167
+ }
168
+
169
+ /// O(1)
170
+ fn size_hint ( & self ) -> ( usize , Option < usize > ) {
171
+ let n = self . buffer . len ( ) - self . index ;
172
+ ( n, Some ( n) )
173
+ }
174
+ }
175
+
126
176
impl < T > EventManager < T > {
127
177
/// Add an entry to the interest list of the epoll file descriptor.
128
178
///
@@ -186,12 +236,12 @@ impl<T> EventManager<T> {
186
236
///
187
237
/// When the value given in timeout does not fit within an `i32` e.g.
188
238
/// `timeout.map(|u| i32::try_from(u).unwrap())`.
189
- pub fn wait (
190
- & mut self ,
239
+ pub fn wait < ' a > (
240
+ & ' a mut self ,
191
241
timeout : Option < u32 > ,
192
- buffer : & mut [ libc:: epoll_event ] ,
193
- output_buffer : & mut [ T ] ,
194
- ) -> Result < i32 , i32 > {
242
+ buffer : & ' a mut [ libc:: epoll_event ] ,
243
+ output_buffer : & ' a mut [ T ] ,
244
+ ) -> Result < Iter < ' a , T > , i32 > {
195
245
// SAFETY: Always safe.
196
246
match unsafe {
197
247
libc:: epoll_wait (
@@ -204,18 +254,13 @@ impl<T> EventManager<T> {
204
254
-1 => Err ( errno ( ) ) ,
205
255
// SAFETY: `x` elements are initialized by `libc::epoll_wait`.
206
256
n @ 0 .. => unsafe {
207
- #[ allow( clippy:: needless_range_loop) ]
208
- for i in 0 ..usize:: try_from ( n) . unwrap_unchecked ( ) {
209
- let event = buffer[ i] ;
210
- // For all events which can fire there exists an entry within `self.events` thus
211
- // it is safe to unwrap here.
212
- let f: * const dyn Fn ( & mut EventManager < T > , EventSet ) -> T = self
213
- . events
214
- . get ( & i32:: try_from ( event. u64 ) . unwrap_unchecked ( ) )
215
- . unwrap_unchecked ( ) ;
216
- output_buffer[ i] = ( * f) ( self , EventSet :: from_bits_unchecked ( event. events ) ) ;
217
- }
218
- Ok ( n)
257
+ let n = usize:: try_from ( n) . unwrap_unchecked ( ) ;
258
+ Ok ( Iter {
259
+ event_manager : self ,
260
+ buffer : & mut buffer[ ..n] ,
261
+ output_buffer : & mut output_buffer[ ..n] ,
262
+ index : 0 ,
263
+ } )
219
264
} ,
220
265
_ => unreachable ! ( ) ,
221
266
}
@@ -286,17 +331,19 @@ mod tests {
286
331
287
332
// The file descriptor has been pre-armed, this will immediately call the respective
288
333
// closure.
289
- let vec = vec ! [ ( ) ] ;
290
- assert_eq ! ( manager. wait( Some ( 10 ) ) , Ok ( vec. as_slice( ) ) ) ;
334
+ let mut iter = manager. wait ( Some ( 10 ) ) . unwrap ( ) ;
335
+ assert_eq ! ( iter. next( ) , Some ( & mut ( ) ) ) ;
336
+ assert_eq ! ( iter. next( ) , None ) ;
291
337
292
338
// As the closure will flip the atomic boolean we assert it has flipped correctly.
293
339
assert ! ( COUNT . load( Ordering :: SeqCst ) ) ;
294
340
295
341
// At this point we have called the closure, since the closure removes the event fd from the
296
342
// interest list of the inner epoll, calling this again should timeout as there are no event
297
343
// fd in the inner epolls interest list which could trigger.
298
- let vec = vec ! [ ] ;
299
- assert_eq ! ( manager. wait( Some ( 10 ) ) , Ok ( vec. as_slice( ) ) ) ;
344
+ let mut iter = manager. wait ( Some ( 10 ) ) . unwrap ( ) ;
345
+ assert_eq ! ( iter. next( ) , None ) ;
346
+
300
347
// As the `EventManager::wait` should timeout the value of the atomic boolean should not be
301
348
// flipped.
302
349
assert ! ( COUNT . load( Ordering :: SeqCst ) ) ;
@@ -329,15 +376,18 @@ mod tests {
329
376
assert ! ( !COUNT . load( Ordering :: SeqCst ) ) ;
330
377
331
378
// As the closure will flip the atomic boolean we assert it has flipped correctly.
332
- let vec = vec ! [ ( ) ] ;
333
- assert_eq ! ( manager. wait( Some ( 10 ) ) , Ok ( vec. as_slice( ) ) ) ;
379
+ let mut iter = manager. wait ( Some ( 10 ) ) . unwrap ( ) ;
380
+ assert_eq ! ( iter. next( ) , Some ( & mut ( ) ) ) ;
381
+ assert_eq ! ( iter. next( ) , None ) ;
382
+
334
383
// As the closure will flip the atomic boolean we assert it has flipped correctly.
335
384
assert ! ( COUNT . load( Ordering :: SeqCst ) ) ;
336
385
337
386
// The file descriptor has been pre-armed, this will immediately call the respective
338
387
// closure.
339
- let vec = vec ! [ ( ) ] ;
340
- assert_eq ! ( manager. wait( Some ( 10 ) ) , Ok ( vec. as_slice( ) ) ) ;
388
+ let mut iter = manager. wait ( Some ( 10 ) ) . unwrap ( ) ;
389
+ assert_eq ! ( iter. next( ) , Some ( & mut ( ) ) ) ;
390
+ assert_eq ! ( iter. next( ) , None ) ;
341
391
// As the closure will flip the atomic boolean we assert it has flipped correctly.
342
392
assert ! ( !COUNT . load( Ordering :: SeqCst ) ) ;
343
393
}
@@ -394,8 +444,12 @@ mod tests {
394
444
}
395
445
396
446
// Check counter are the correct values
397
- let arr = [ 0 ; FIRING ] ;
398
- assert_eq ! ( manager. wait( None ) , Ok ( arr. as_slice( ) ) ) ;
447
+ let mut iter = manager. wait ( None ) . unwrap ( ) ;
448
+ for _ in 0 ..FIRING {
449
+ assert_eq ! ( iter. next( ) , Some ( & mut 0 ) ) ;
450
+ }
451
+ assert_eq ! ( iter. next( ) , None ) ;
452
+
399
453
for i in set {
400
454
assert_eq ! ( subscribers[ i] . 1 . load( Ordering :: SeqCst ) , 1 ) ;
401
455
}
@@ -429,7 +483,9 @@ mod tests {
429
483
. add ( event_fd, EventSet :: IN , Box :: new ( |_, _| Err ( ( ) ) ) )
430
484
. unwrap ( ) ;
431
485
432
- let arr = [ Ok ( ( ) ) , Err ( ( ) ) ] ;
433
- assert_eq ! ( manager. wait( None ) , Ok ( arr. as_slice( ) ) ) ;
486
+ let mut iter = manager. wait ( None ) . unwrap ( ) ;
487
+ assert_eq ! ( iter. next( ) , Some ( & mut Ok ( ( ) ) ) ) ;
488
+ assert_eq ! ( iter. next( ) , Some ( & mut Err ( ( ) ) ) ) ;
489
+ assert_eq ! ( iter. next( ) , None ) ;
434
490
}
435
491
}
0 commit comments