Skip to content

Commit d0ea7c1

Browse files
committed
Pass WeakFileDescriptionRef to the callback to check if the file description is closed
1 parent 0e44ded commit d0ea7c1

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

src/shims/unix/fd.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ impl WeakFileDescriptionRef {
296296
}
297297
}
298298

299+
impl VisitProvenance for WeakFileDescriptionRef {
300+
fn visit_provenance(&self, _visit: &mut VisitWith<'_>) {
301+
// All our WeakFileDescriptionRef do not have any tags.
302+
}
303+
}
304+
299305
/// A unique id for file descriptions. While we could use the address, considering that
300306
/// is definitely unique, the address would expose interpreter internal state when used
301307
/// for sorting things. So instead we generate a unique id per file description that stays

src/shims/unix/linux/epoll.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::io;
44
use std::rc::{Rc, Weak};
55
use std::time::Duration;
66

7-
use crate::shims::unix::fd::FdId;
7+
use crate::shims::unix::fd::{FdId, WeakFileDescriptionRef};
88
use crate::shims::unix::*;
99
use 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

Comments
 (0)