@@ -473,4 +473,51 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
473473 }
474474 Ok ( ( ) )
475475 }
476+
477+ /// Callback function after epoll_wait unblocks
478+ fn blocking_epoll_callback (
479+ & mut self ,
480+ epfd : i32 ,
481+ place : & MPlaceTy < ' tcx > ,
482+ event : & MPlaceTy < ' tcx > ,
483+ ) -> InterpResult < ' tcx > {
484+ let this = self . eval_context_mut ( ) ;
485+
486+ let Some ( epfd) = this. machine . fds . get_ref ( epfd) else {
487+ let result_value = this. fd_not_found ( ) ?;
488+ this. write_scalar ( Scalar :: from_i32 ( result_value) , place) ?;
489+ return Ok ( ( ) ) ;
490+ } ;
491+ let mut binding = epfd. borrow_mut ( ) ;
492+ let epoll_file_description = & mut binding
493+ . downcast_mut :: < Epoll > ( )
494+ . ok_or_else ( || err_unsup_format ! ( "non-epoll FD passed to `epoll_wait`" ) ) ?;
495+
496+ let binding = epoll_file_description. get_ready_list ( ) ;
497+ let mut ready_list = binding. borrow_mut ( ) ;
498+ let mut num_of_events: i32 = 0 ;
499+ let mut array_iter = this. project_array_fields ( event) ?;
500+
501+ while let Some ( ( epoll_key, epoll_return) ) = ready_list. pop_first ( ) {
502+ // If the file description is fully close, the entry for corresponding FdID in the
503+ // global epoll event interest table would be empty.
504+ if this. machine . epoll_interests . get_epoll_interest ( epoll_key. 0 ) . is_some ( ) {
505+ // Return notification to the caller if the file description is not fully closed.
506+ if let Some ( des) = array_iter. next ( this) ? {
507+ this. write_int_fields_named (
508+ & [
509+ ( "events" , epoll_return. events . into ( ) ) ,
510+ ( "u64" , epoll_return. data . into ( ) ) ,
511+ ] ,
512+ & des. 1 ,
513+ ) ?;
514+ num_of_events = num_of_events. checked_add ( 1 ) . unwrap ( ) ;
515+ } else {
516+ break ;
517+ }
518+ }
519+ }
520+ this. write_scalar ( Scalar :: from_i32 ( num_of_events) , place) ?;
521+ Ok ( ( ) )
522+ }
476523}
0 commit comments