@@ -4,6 +4,7 @@ use core::task::Waker;
4
4
5
5
use std:: io:: { self , ErrorKind } ;
6
6
use std:: os:: fd:: { AsRawFd , FromRawFd , OwnedFd , RawFd } ;
7
+ use std:: sync:: MutexGuard ;
7
8
8
9
use enumset:: { EnumSet , EnumSetType } ;
9
10
@@ -82,13 +83,15 @@ struct Registration {
82
83
struct Registrations < const N : usize > {
83
84
vec : heapless:: Vec < Registration , N > ,
84
85
event_fd : Option < OwnedFd > ,
86
+ waiting : usize ,
85
87
}
86
88
87
89
impl < const N : usize > Registrations < N > {
88
90
const fn new ( ) -> Self {
89
91
Self {
90
92
vec : heapless:: Vec :: new ( ) ,
91
93
event_fd : None ,
94
+ waiting : 0 ,
92
95
}
93
96
}
94
97
@@ -129,8 +132,6 @@ impl<const N: usize> Registrations<N> {
129
132
130
133
self . vec . swap_remove ( index) ;
131
134
132
- self . notify ( ) ?;
133
-
134
135
Ok ( ( ) )
135
136
}
136
137
@@ -147,8 +148,6 @@ impl<const N: usize> Registrations<N> {
147
148
}
148
149
}
149
150
150
- self . notify ( ) ?;
151
-
152
151
Ok ( ( ) )
153
152
}
154
153
@@ -312,13 +311,15 @@ impl<const N: usize> Registrations<N> {
312
311
313
312
pub struct Reactor < const N : usize > {
314
313
registrations : std:: sync:: Mutex < Registrations < N > > ,
314
+ condvar : std:: sync:: Condvar ,
315
315
started : AtomicBool ,
316
316
}
317
317
318
318
impl < const N : usize > Reactor < N > {
319
319
const fn new ( ) -> Self {
320
320
Self {
321
321
registrations : std:: sync:: Mutex :: new ( Registrations :: new ( ) ) ,
322
+ condvar : std:: sync:: Condvar :: new ( ) ,
322
323
started : AtomicBool :: new ( false ) ,
323
324
}
324
325
}
@@ -340,23 +341,23 @@ impl<const N: usize> Reactor<N> {
340
341
}
341
342
342
343
pub ( crate ) fn register ( & self , fd : RawFd ) -> io:: Result < ( ) > {
343
- self . lock ( |regs| regs. register ( fd) )
344
+ self . lock_modify ( |regs| regs. register ( fd) )
344
345
}
345
346
346
347
pub ( crate ) fn deregister ( & self , fd : RawFd ) -> io:: Result < ( ) > {
347
- self . lock ( |regs| regs. deregister ( fd) )
348
+ self . lock_modify ( |regs| regs. deregister ( fd) )
348
349
}
349
350
350
351
// pub(crate) fn set(&self, fd: RawFd, event: Event, waker: &Waker) -> io::Result<()> {
351
352
// self.lock(|regs| regs.set(fd, event, waker))
352
353
// }
353
354
354
355
pub ( crate ) fn fetch ( & self , fd : RawFd , event : Event ) -> io:: Result < bool > {
355
- self . lock ( |regs| regs. fetch ( fd, event) )
356
+ self . lock_modify ( |regs| regs. fetch ( fd, event) )
356
357
}
357
358
358
359
pub ( crate ) fn fetch_or_set ( & self , fd : RawFd , event : Event , waker : & Waker ) -> io:: Result < bool > {
359
- self . lock ( |regs| {
360
+ self . lock_modify ( |regs| {
360
361
if regs. fetch ( fd, event) ? {
361
362
Ok ( true )
362
363
} else {
@@ -368,58 +369,100 @@ impl<const N: usize> Reactor<N> {
368
369
}
369
370
370
371
fn run ( & self ) -> io:: Result < ( ) > {
371
- if !self . lock ( Registrations :: create_notification) ? {
372
+ if !self . lock ( | mut guard| guard . create_notification ( ) ) ? {
372
373
Err ( ErrorKind :: AlreadyExists ) ?;
373
374
}
374
375
375
376
debug ! ( "Running" ) ;
376
377
378
+ let mut fds = Fds :: new ( ) ;
379
+ let mut update = false ;
380
+
377
381
let result = loop {
378
- let result = self . wait ( ) ;
382
+ let max = self . lock_apply ( |inner| {
383
+ if !update {
384
+ update = true ;
385
+ } else {
386
+ inner. update_events ( & fds) ?;
387
+ }
388
+
389
+ inner. set_fds ( & mut fds)
390
+ } ) ;
391
+
392
+ let result = match max {
393
+ Err ( err) => Err ( err) ,
394
+ Ok ( None ) => unreachable ! ( "EventFD is not there?" ) ,
395
+ Ok ( Some ( max) ) => {
396
+ debug ! ( "Start select" ) ;
397
+
398
+ let result = syscall_los ! ( unsafe {
399
+ sys:: select(
400
+ max + 1 ,
401
+ fds. read. assume_init_mut( ) ,
402
+ fds. write. assume_init_mut( ) ,
403
+ fds. except. assume_init_mut( ) ,
404
+ core:: ptr:: null_mut( ) ,
405
+ )
406
+ } ) ;
407
+
408
+ debug ! ( "End select" ) ;
409
+
410
+ result. map ( |_| ( ) )
411
+ }
412
+ } ;
379
413
380
414
if result. is_err ( ) {
381
415
break result;
382
416
}
383
417
} ;
384
418
385
- if !self . lock ( Registrations :: destroy_notification) ? {
419
+ if !self . lock ( | mut guard| guard . destroy_notification ( ) ) ? {
386
420
Err ( ErrorKind :: NotFound ) ?;
387
421
}
388
422
389
423
result
390
424
}
391
425
392
- fn wait ( & self ) -> io:: Result < ( ) > {
393
- let mut fds = Fds :: new ( ) ;
394
-
395
- if let Some ( max) = self . lock ( |inner| inner. set_fds ( & mut fds) ) ? {
396
- debug ! ( "Start select" ) ;
426
+ fn lock_modify < F , R > ( & self , f : F ) -> io:: Result < R >
427
+ where
428
+ F : FnOnce ( & mut Registrations < N > ) -> io:: Result < R > ,
429
+ {
430
+ self . lock ( |mut guard| {
431
+ guard. waiting += 1 ;
397
432
398
- syscall_los ! ( unsafe {
399
- sys:: select(
400
- max + 1 ,
401
- fds. read. assume_init_mut( ) ,
402
- fds. write. assume_init_mut( ) ,
403
- fds. except. assume_init_mut( ) ,
404
- core:: ptr:: null_mut( ) ,
405
- )
406
- } ) ?;
433
+ let result = f ( & mut guard) ;
407
434
408
- debug ! ( "End select" ) ;
435
+ guard . notify ( ) ? ;
409
436
410
- self . lock ( |inner| inner. update_events ( & fds) ) ?;
411
- }
437
+ let _guard = self
438
+ . condvar
439
+ . wait_while ( guard, |registrations| registrations. waiting > 0 )
440
+ . unwrap ( ) ;
412
441
413
- Ok ( ( ) )
442
+ result
443
+ } )
414
444
}
415
445
416
- fn lock < F , R > ( & self , f : F ) -> io:: Result < R >
446
+ fn lock_apply < F , R > ( & self , f : F ) -> io:: Result < R >
417
447
where
418
448
F : FnOnce ( & mut Registrations < N > ) -> io:: Result < R > ,
419
449
{
420
- let mut inner = self . registrations . lock ( ) . unwrap ( ) ;
450
+ self . lock ( |mut guard| {
451
+ let result = f ( & mut guard) ;
452
+
453
+ guard. waiting = 0 ;
421
454
422
- f ( & mut inner)
455
+ self . condvar . notify_all ( ) ;
456
+
457
+ result
458
+ } )
459
+ }
460
+
461
+ fn lock < F , R > ( & self , f : F ) -> io:: Result < R >
462
+ where
463
+ F : FnOnce ( MutexGuard < Registrations < N > > ) -> io:: Result < R > ,
464
+ {
465
+ f ( self . registrations . lock ( ) . unwrap ( ) )
423
466
}
424
467
}
425
468
0 commit comments