@@ -4,7 +4,7 @@ use std::io;
44use std:: rc:: { Rc , Weak } ;
55use std:: time:: Duration ;
66
7- use crate :: shims:: unix:: fd:: FdId ;
7+ use crate :: shims:: unix:: fd:: { FdId , WeakFileDescriptionRef } ;
88use crate :: shims:: unix:: * ;
99use crate :: * ;
1010
@@ -402,6 +402,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
402402 this. write_scalar ( Scalar :: from_i32 ( result_value) , & dest) ?;
403403 return Ok ( ( ) ) ;
404404 } ;
405+ // Create a weak ref of epfd and pass it to callback so we will make sure that epfd
406+ // is not close after the thread unblocks.
407+ let weak_epfd = epfd. downgrade ( ) ;
408+
405409 let mut binding = epfd. borrow_mut ( ) ;
406410 let epoll_file_description = & mut binding
407411 . downcast_mut :: < Epoll > ( )
@@ -424,11 +428,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
424428 callback ! (
425429 @capture<' tcx> {
426430 epfd_value: i32 ,
431+ weak_epfd: WeakFileDescriptionRef ,
427432 dest: MPlaceTy <' tcx>,
428433 event: MPlaceTy <' tcx>,
429434 }
430435 @unblock = |this| {
431- this. blocking_epoll_callback( epfd_value, & dest, & event) ?;
436+ this. blocking_epoll_callback( epfd_value, weak_epfd , & dest, & event) ?;
432437 Ok ( ( ) )
433438 }
434439 @timeout = |this| {
@@ -440,7 +445,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
440445 }
441446 } else {
442447 // Non-blocking with notification returned.
443- this. blocking_epoll_callback ( epfd_value, & dest, & event) ?;
448+ this. blocking_epoll_callback ( epfd_value, weak_epfd , & dest, & event) ?;
444449 return Ok ( ( ) ) ;
445450 }
446451
@@ -450,17 +455,17 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
450455 /// Callback function after epoll_wait unblocks
451456 fn blocking_epoll_callback (
452457 & mut self ,
453- epfd : i32 ,
458+ epfd_value : i32 ,
459+ weak_epfd : WeakFileDescriptionRef ,
454460 dest : & MPlaceTy < ' tcx > ,
455461 event : & MPlaceTy < ' tcx > ,
456462 ) -> InterpResult < ' tcx > {
457463 let this = self . eval_context_mut ( ) ;
458464
459- let Some ( epfd) = this. machine . fds . get_ref ( epfd) else {
460- let result_value = this. fd_not_found ( ) ?;
461- this. write_scalar ( Scalar :: from_i32 ( result_value) , dest) ?;
462- return Ok ( ( ) ) ;
465+ let Some ( epfd) = weak_epfd. upgrade ( ) else {
466+ throw_unsup_format ! ( "epoll file descriptor {epfd_value} is closed while blocking." )
463467 } ;
468+
464469 let mut binding = epfd. borrow_mut ( ) ;
465470 let epoll_file_description = & mut binding
466471 . downcast_mut :: < Epoll > ( )
0 commit comments