@@ -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
@@ -13,9 +14,13 @@ use libc as sys;
13
14
14
15
use crate :: { syscall, syscall_los, syscall_los_eagain} ;
15
16
17
+ // For ESP-IDF sys::FDSETSIZE is currently wrongly set to 1024 in the `libc` crate
18
+ // Therefore, use a custom value for now
19
+ #[ cfg( target_os = "espidf" ) ]
16
20
const MAX_REGISTRATIONS : usize = 20 ;
17
21
18
- //const FD_SEGMENT: usize = sys::FD_SETSIZE / core::mem::size_of::<sys::fd_set>();
22
+ #[ cfg( not( target_os = "espidf" ) ) ]
23
+ const MAX_REGISTRATIONS : usize = sys:: FD_SETSIZE ;
19
24
20
25
#[ derive( EnumSetType , Debug ) ]
21
26
pub ( crate ) enum Event {
@@ -82,13 +87,15 @@ struct Registration {
82
87
struct Registrations < const N : usize > {
83
88
vec : heapless:: Vec < Registration , N > ,
84
89
event_fd : Option < OwnedFd > ,
90
+ waiting : usize ,
85
91
}
86
92
87
93
impl < const N : usize > Registrations < N > {
88
94
const fn new ( ) -> Self {
89
95
Self {
90
96
vec : heapless:: Vec :: new ( ) ,
91
97
event_fd : None ,
98
+ waiting : 0 ,
92
99
}
93
100
}
94
101
@@ -103,7 +110,7 @@ impl<const N: usize> Registrations<N> {
103
110
Err ( ErrorKind :: InvalidInput ) ?;
104
111
}
105
112
106
- if fd >= sys:: FD_SETSIZE as RawFd {
113
+ if fd >= sys:: FD_SETSIZE as RawFd || fd >= N as RawFd {
107
114
Err ( ErrorKind :: OutOfMemory ) ?;
108
115
}
109
116
@@ -129,8 +136,6 @@ impl<const N: usize> Registrations<N> {
129
136
130
137
self . vec . swap_remove ( index) ;
131
138
132
- self . notify ( ) ?;
133
-
134
139
Ok ( ( ) )
135
140
}
136
141
@@ -147,8 +152,6 @@ impl<const N: usize> Registrations<N> {
147
152
}
148
153
}
149
154
150
- self . notify ( ) ?;
151
-
152
155
Ok ( ( ) )
153
156
}
154
157
@@ -312,13 +315,15 @@ impl<const N: usize> Registrations<N> {
312
315
313
316
pub struct Reactor < const N : usize > {
314
317
registrations : std:: sync:: Mutex < Registrations < N > > ,
318
+ condvar : std:: sync:: Condvar ,
315
319
started : AtomicBool ,
316
320
}
317
321
318
322
impl < const N : usize > Reactor < N > {
319
323
const fn new ( ) -> Self {
320
324
Self {
321
325
registrations : std:: sync:: Mutex :: new ( Registrations :: new ( ) ) ,
326
+ condvar : std:: sync:: Condvar :: new ( ) ,
322
327
started : AtomicBool :: new ( false ) ,
323
328
}
324
329
}
@@ -340,23 +345,23 @@ impl<const N: usize> Reactor<N> {
340
345
}
341
346
342
347
pub ( crate ) fn register ( & self , fd : RawFd ) -> io:: Result < ( ) > {
343
- self . lock ( |regs| regs. register ( fd) )
348
+ self . modify ( |regs| regs. register ( fd) )
344
349
}
345
350
346
351
pub ( crate ) fn deregister ( & self , fd : RawFd ) -> io:: Result < ( ) > {
347
- self . lock ( |regs| regs. deregister ( fd) )
352
+ self . modify ( |regs| regs. deregister ( fd) )
348
353
}
349
354
350
355
// pub(crate) fn set(&self, fd: RawFd, event: Event, waker: &Waker) -> io::Result<()> {
351
356
// self.lock(|regs| regs.set(fd, event, waker))
352
357
// }
353
358
354
359
pub ( crate ) fn fetch ( & self , fd : RawFd , event : Event ) -> io:: Result < bool > {
355
- self . lock ( |regs| regs. fetch ( fd, event) )
360
+ self . modify ( |regs| regs. fetch ( fd, event) )
356
361
}
357
362
358
363
pub ( crate ) fn fetch_or_set ( & self , fd : RawFd , event : Event , waker : & Waker ) -> io:: Result < bool > {
359
- self . lock ( |regs| {
364
+ self . modify ( |regs| {
360
365
if regs. fetch ( fd, event) ? {
361
366
Ok ( true )
362
367
} else {
@@ -368,58 +373,100 @@ impl<const N: usize> Reactor<N> {
368
373
}
369
374
370
375
fn run ( & self ) -> io:: Result < ( ) > {
371
- if !self . lock ( Registrations :: create_notification) ? {
376
+ if !self . lock ( | mut guard| guard . create_notification ( ) ) ? {
372
377
Err ( ErrorKind :: AlreadyExists ) ?;
373
378
}
374
379
375
380
debug ! ( "Running" ) ;
376
381
382
+ let mut fds = Fds :: new ( ) ;
383
+ let mut update = false ;
384
+
377
385
let result = loop {
378
- let result = self . wait ( ) ;
386
+ let max = self . apply ( |inner| {
387
+ if !update {
388
+ update = true ;
389
+ } else {
390
+ inner. update_events ( & fds) ?;
391
+ }
392
+
393
+ inner. set_fds ( & mut fds)
394
+ } ) ;
395
+
396
+ let result = match max {
397
+ Err ( err) => Err ( err) ,
398
+ Ok ( None ) => unreachable ! ( "EventFD is not there?" ) ,
399
+ Ok ( Some ( max) ) => {
400
+ debug ! ( "Start select" ) ;
401
+
402
+ let result = syscall_los ! ( unsafe {
403
+ sys:: select(
404
+ max + 1 ,
405
+ fds. read. assume_init_mut( ) ,
406
+ fds. write. assume_init_mut( ) ,
407
+ fds. except. assume_init_mut( ) ,
408
+ core:: ptr:: null_mut( ) ,
409
+ )
410
+ } ) ;
411
+
412
+ debug ! ( "End select" ) ;
413
+
414
+ result. map ( |_| ( ) )
415
+ }
416
+ } ;
379
417
380
418
if result. is_err ( ) {
381
419
break result;
382
420
}
383
421
} ;
384
422
385
- if !self . lock ( Registrations :: destroy_notification) ? {
423
+ if !self . lock ( | mut guard| guard . destroy_notification ( ) ) ? {
386
424
Err ( ErrorKind :: NotFound ) ?;
387
425
}
388
426
389
427
result
390
428
}
391
429
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" ) ;
430
+ fn modify < F , R > ( & self , f : F ) -> io:: Result < R >
431
+ where
432
+ F : FnOnce ( & mut Registrations < N > ) -> io:: Result < R > ,
433
+ {
434
+ self . lock ( |mut guard| {
435
+ guard. waiting += 1 ;
397
436
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
- } ) ?;
437
+ let result = f ( & mut guard) ;
407
438
408
- debug ! ( "End select" ) ;
439
+ guard . notify ( ) ? ;
409
440
410
- self . lock ( |inner| inner. update_events ( & fds) ) ?;
411
- }
441
+ let _guard = self
442
+ . condvar
443
+ . wait_while ( guard, |registrations| registrations. waiting > 0 )
444
+ . unwrap ( ) ;
412
445
413
- Ok ( ( ) )
446
+ result
447
+ } )
414
448
}
415
449
416
- fn lock < F , R > ( & self , f : F ) -> io:: Result < R >
450
+ fn apply < F , R > ( & self , f : F ) -> io:: Result < R >
417
451
where
418
452
F : FnOnce ( & mut Registrations < N > ) -> io:: Result < R > ,
419
453
{
420
- let mut inner = self . registrations . lock ( ) . unwrap ( ) ;
454
+ self . lock ( |mut guard| {
455
+ let result = f ( & mut guard) ;
456
+
457
+ guard. waiting = 0 ;
421
458
422
- f ( & mut inner)
459
+ self . condvar . notify_all ( ) ;
460
+
461
+ result
462
+ } )
463
+ }
464
+
465
+ fn lock < F , R > ( & self , f : F ) -> io:: Result < R >
466
+ where
467
+ F : FnOnce ( MutexGuard < Registrations < N > > ) -> io:: Result < R > ,
468
+ {
469
+ f ( self . registrations . lock ( ) . unwrap ( ) )
423
470
}
424
471
}
425
472
0 commit comments