@@ -430,7 +430,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
430430 let epfd_value = this. read_scalar ( epfd) ?. to_i32 ( ) ?;
431431 let events = this. read_immediate ( events_op) ?;
432432 let maxevents = this. read_scalar ( maxevents) ?. to_i32 ( ) ?;
433- let timeout = this. read_scalar ( timeout) ?. to_u32 ( ) ?;
433+ let timeout = this. read_scalar ( timeout) ?. to_i32 ( ) ?;
434434
435435 if epfd_value <= 0 || maxevents <= 0 {
436436 let einval = this. eval_libc ( "EINVAL" ) ;
@@ -467,42 +467,43 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
467467 ready_list_empty = binding. borrow_mut ( ) . is_empty ( ) ;
468468 thread_ids = epoll_file_description. thread_id . borrow_mut ( ) ;
469469 }
470-
471- if ready_list_empty {
472- if timeout == 0 {
473- // Non-blocking with no notification returned.
474- this. write_scalar ( Scalar :: from_i32 ( 0 ) , & dest) ?;
475- } else {
476- // Blocking
477- let duration = Duration :: from_millis ( timeout. into ( ) ) ;
478- thread_ids. push ( this. active_thread ( ) ) ;
479- this. block_thread (
480- BlockReason :: Epoll ,
481- Some ( ( TimeoutClock :: Monotonic , TimeoutAnchor :: Relative , duration) ) ,
482- callback ! (
483- @capture<' tcx> {
484- epfd_value: i32 ,
485- weak_epfd: WeakFileDescriptionRef ,
486- dest: MPlaceTy <' tcx>,
487- event: MPlaceTy <' tcx>,
488- }
489- @unblock = |this| {
490- this. blocking_epoll_callback( epfd_value, weak_epfd, & dest, & event) ?;
491- Ok ( ( ) )
492- }
493- @timeout = |this| {
494- // No notification after blocking timeout.
495- this. write_scalar( Scalar :: from_i32( 0 ) , & dest) ?;
496- Ok ( ( ) )
497- }
498- ) ,
499- ) ;
500- }
501- } else {
502- // Immediately return epoll notification without blocking.
470+ if timeout == 0 || !ready_list_empty {
471+ // If the ready list is not empty, or the timeout is 0, we can return immediately.
503472 this. blocking_epoll_callback ( epfd_value, weak_epfd, & dest, & event) ?;
473+ } else {
474+ // Blocking
475+ let timeout = match timeout {
476+ 0 .. => {
477+ let duration = Duration :: from_millis ( timeout. try_into ( ) . unwrap ( ) ) ;
478+ Some ( ( TimeoutClock :: Monotonic , TimeoutAnchor :: Relative , duration) )
479+ }
480+ // If timeout value less than 0, block indefinitely until a notification
481+ // is returned.
482+ ..0 => None ,
483+ } ;
484+ thread_ids. push ( this. active_thread ( ) ) ;
485+ this. block_thread (
486+ BlockReason :: Epoll ,
487+ timeout,
488+ callback ! (
489+ @capture<' tcx> {
490+ epfd_value: i32 ,
491+ weak_epfd: WeakFileDescriptionRef ,
492+ dest: MPlaceTy <' tcx>,
493+ event: MPlaceTy <' tcx>,
494+ }
495+ @unblock = |this| {
496+ this. blocking_epoll_callback( epfd_value, weak_epfd, & dest, & event) ?;
497+ Ok ( ( ) )
498+ }
499+ @timeout = |this| {
500+ // No notification after blocking timeout.
501+ this. write_scalar( Scalar :: from_i32( 0 ) , & dest) ?;
502+ Ok ( ( ) )
503+ }
504+ ) ,
505+ ) ;
504506 }
505-
506507 Ok ( ( ) )
507508 }
508509
0 commit comments