Skip to content

Commit f139c72

Browse files
committed
Previous change before applying suggestion
1 parent 4ca1db2 commit f139c72

File tree

6 files changed

+61
-47
lines changed

6 files changed

+61
-47
lines changed

src/concurrency/thread.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ pub enum BlockReason {
172172
Futex { addr: u64 },
173173
/// Blocked on an InitOnce.
174174
InitOnce(InitOnceId),
175+
/// Blocked on epoll
176+
Epoll,
175177
}
176178

177179
/// The state of a thread.

src/machine.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -958,11 +958,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
958958

959959
#[inline(always)]
960960
fn find_mir_or_eval_fn(
961-
ecx: &mut MiriInterpCx<'tcx>,
961+
ecx: &'tcx mut MiriInterpCx<'tcx>,
962962
instance: ty::Instance<'tcx>,
963963
abi: Abi,
964-
args: &[FnArg<'tcx, Provenance>],
965-
dest: &MPlaceTy<'tcx>,
964+
args: &'tcx [FnArg<'tcx, Provenance>],
965+
dest: &'tcx MPlaceTy<'tcx>,
966966
ret: Option<mir::BasicBlock>,
967967
unwind: mir::UnwindAction,
968968
) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -985,11 +985,11 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
985985

986986
#[inline(always)]
987987
fn call_extra_fn(
988-
ecx: &mut MiriInterpCx<'tcx>,
988+
ecx: &'tcx mut MiriInterpCx<'tcx>,
989989
fn_val: DynSym,
990990
abi: Abi,
991-
args: &[FnArg<'tcx, Provenance>],
992-
dest: &MPlaceTy<'tcx>,
991+
args: &'tcx [FnArg<'tcx, Provenance>],
992+
dest: &'tcx MPlaceTy<'tcx>,
993993
ret: Option<mir::BasicBlock>,
994994
unwind: mir::UnwindAction,
995995
) -> InterpResult<'tcx> {

src/shims/foreign_items.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4141
link_name: Symbol,
4242
abi: Abi,
4343
args: &[OpTy<'tcx>],
44-
dest: &MPlaceTy<'tcx>,
44+
dest: &'tcx MPlaceTy<'tcx>,
4545
ret: Option<mir::BasicBlock>,
4646
unwind: mir::UnwindAction,
4747
) -> InterpResult<'tcx, Option<(&'tcx mir::Body<'tcx>, ty::Instance<'tcx>)>> {
@@ -109,7 +109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
109109
sym: DynSym,
110110
abi: Abi,
111111
args: &[OpTy<'tcx>],
112-
dest: &MPlaceTy<'tcx>,
112+
dest: &'tcx MPlaceTy<'tcx>,
113113
ret: Option<mir::BasicBlock>,
114114
unwind: mir::UnwindAction,
115115
) -> InterpResult<'tcx> {
@@ -221,7 +221,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
221221
link_name: Symbol,
222222
abi: Abi,
223223
args: &[OpTy<'tcx>],
224-
dest: &MPlaceTy<'tcx>,
224+
dest: &'tcx MPlaceTy<'tcx>,
225225
) -> InterpResult<'tcx, EmulateItemResult> {
226226
let this = self.eval_context_mut();
227227

src/shims/unix/foreign_items.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
4646
link_name: Symbol,
4747
abi: Abi,
4848
args: &[OpTy<'tcx>],
49-
dest: &MPlaceTy<'tcx>,
49+
dest: &'tcx MPlaceTy<'tcx>,
5050
) -> InterpResult<'tcx, EmulateItemResult> {
5151
let this = self.eval_context_mut();
5252

src/shims/unix/linux/epoll.rs

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::cell::RefCell;
22
use std::collections::BTreeMap;
33
use std::io;
44
use std::rc::{Rc, Weak};
5+
use std::time::Duration;
56

67
use crate::shims::unix::fd::FdId;
78
use crate::shims::unix::*;
@@ -378,62 +379,74 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
378379
events_op: &OpTy<'tcx>,
379380
maxevents: &OpTy<'tcx>,
380381
timeout: &OpTy<'tcx>,
381-
) -> InterpResult<'tcx, Scalar> {
382+
place: &'tcx MPlaceTy<'tcx>,
383+
) -> InterpResult<'tcx> {
382384
let this = self.eval_context_mut();
383385

384-
let epfd = this.read_scalar(epfd)?.to_i32()?;
386+
let epfd_value = this.read_scalar(epfd)?.to_i32()?;
385387
let maxevents = this.read_scalar(maxevents)?.to_i32()?;
386388
let event = this.deref_pointer_as(
387389
events_op,
388390
this.libc_array_ty_layout("epoll_event", maxevents.try_into().unwrap()),
389391
)?;
390-
let timeout = this.read_scalar(timeout)?.to_i32()?;
392+
let timeout = this.read_scalar(timeout)?.to_u32()?;
391393

392-
if epfd <= 0 {
394+
if epfd_value <= 0 {
393395
let einval = this.eval_libc("EINVAL");
394396
this.set_last_error(einval)?;
395-
return Ok(Scalar::from_i32(-1));
396-
}
397-
// FIXME: Implement blocking support
398-
if timeout != 0 {
399-
throw_unsup_format!("epoll_wait: timeout value can only be 0");
397+
this.write_scalar(Scalar::from_i32(-1), place)?;
398+
return Ok(());
400399
}
401-
402-
let Some(epfd) = this.machine.fds.get_ref(epfd) else {
403-
return Ok(Scalar::from_i32(this.fd_not_found()?));
400+
let Some(epfd) = this.machine.fds.get_ref(epfd_value) else {
401+
let result_value = this.fd_not_found()?;
402+
this.write_scalar(Scalar::from_i32(result_value), place)?;
403+
return Ok(());
404404
};
405405
let mut binding = epfd.borrow_mut();
406406
let epoll_file_description = &mut binding
407407
.downcast_mut::<Epoll>()
408408
.ok_or_else(|| err_unsup_format!("non-epoll FD passed to `epoll_wait`"))?;
409409

410410
let binding = epoll_file_description.get_ready_list();
411-
let mut ready_list = binding.borrow_mut();
412-
let mut num_of_events: i32 = 0;
413-
let mut array_iter = this.project_array_fields(&event)?;
411+
let ready_list = binding.borrow_mut();
414412

415-
while let Some((epoll_key, epoll_return)) = ready_list.pop_first() {
416-
// If the file description is fully close, the entry for corresponding FdID in the
417-
// global epoll event interest table would be empty.
418-
if this.machine.epoll_interests.get_epoll_interest(epoll_key.0).is_some() {
419-
// Return notification to the caller if the file description is not fully closed.
420-
if let Some(des) = array_iter.next(this)? {
421-
this.write_int_fields_named(
422-
&[
423-
("events", epoll_return.events.into()),
424-
("u64", epoll_return.data.into()),
425-
],
426-
&des.1,
427-
)?;
428-
num_of_events = num_of_events.checked_add(1).unwrap();
429-
} else {
430-
break;
431-
}
413+
if ready_list.is_empty() {
414+
if timeout == 0 {
415+
// Non-blocking with no notification returned.
416+
this.write_scalar(Scalar::from_i32(0), place)?;
417+
return Ok(());
418+
} else {
419+
// Blocking
420+
let duration = Duration::from_secs(timeout.into());
421+
this.block_thread(
422+
BlockReason::Epoll,
423+
Some((TimeoutClock::Monotonic, TimeoutAnchor::Relative, duration)),
424+
callback!(
425+
@capture<'tcx> {
426+
epfd_value: i32,
427+
place: &'tcx MPlaceTy<'tcx>,
428+
event: MPlaceTy<'tcx>,
429+
}
430+
@unblock = |this| {
431+
this.blocking_epoll_callback(epfd_value, place, &event);
432+
Ok(())
433+
}
434+
@timeout = |this| {
435+
this.write_scalar(Scalar::from_i32(0), place)?;
436+
Ok(())
437+
}
438+
),
439+
);
432440
}
441+
} else {
442+
// Non-blocking with notification returned.
443+
this.blocking_epoll_callback(epfd_value, place, &event);
444+
return Ok(());
433445
}
434-
Ok(Scalar::from_i32(num_of_events))
435-
}
436446

447+
Ok(())
448+
}
449+
437450
/// For a specific unique file descriptor id, get its ready events and update
438451
/// the corresponding ready list. This function is called whenever a file description
439452
/// is registered with epoll, or when read, write, or close operations are performed,

src/shims/unix/linux/foreign_items.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2121
link_name: Symbol,
2222
abi: Abi,
2323
args: &[OpTy<'tcx>],
24-
dest: &MPlaceTy<'tcx>,
24+
dest: &'tcx MPlaceTy<'tcx>,
2525
) -> InterpResult<'tcx, EmulateItemResult> {
2626
let this = self.eval_context_mut();
2727

@@ -62,8 +62,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
6262
"epoll_wait" => {
6363
let [epfd, events, maxevents, timeout] =
6464
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
65-
let result = this.epoll_wait(epfd, events, maxevents, timeout)?;
66-
this.write_scalar(result, dest)?;
65+
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
6766
}
6867
"eventfd" => {
6968
let [val, flag] =

0 commit comments

Comments
 (0)