Skip to content

Commit e6b19bc

Browse files
committed
Fail attempt 2: If update_readiness is only implement under SocketPair and Eventfd, epoll_ctl can't find a way to invoke it~
1 parent 61e8e1a commit e6b19bc

File tree

5 files changed

+64
-47
lines changed

5 files changed

+64
-47
lines changed

src/shims/unix/fd.rs

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ pub trait FileDescription: std::fmt::Debug + Any {
5151

5252
fn close<'tcx>(
5353
self: Box<Self>,
54-
_ecx: &mut MiriInterpCx<'tcx>,
5554
_communicate_allowed: bool,
5655
) -> InterpResult<'tcx, io::Result<()>> {
5756
throw_unsup_format!("cannot close {}", self.name());
@@ -198,13 +197,11 @@ impl FileDescriptor {
198197
RefMut::map(self.0.borrow_mut(), |fd| fd.as_mut())
199198
}
200199

201-
pub fn close<'ctx>(self,
202-
ecx: &mut MiriInterpCx<'tcx>,
203-
communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
200+
pub fn close<'ctx>(self, communicate_allowed: bool) -> InterpResult<'ctx, io::Result<()>> {
204201
// Destroy this `Rc` using `into_inner` so we can call `close` instead of
205202
// implicitly running the destructor of the file description.
206203
match Rc::into_inner(self.0) {
207-
Some(fd) => RefCell::into_inner(fd).close(ecx, communicate_allowed),
204+
Some(fd) => RefCell::into_inner(fd).close(communicate_allowed),
208205
None => Ok(Ok(())),
209206
}
210207
}
@@ -412,33 +409,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
412409
Ok((-1).into())
413410
}
414411

415-
/// Functions to update the ready list of an epoll_event.
416-
fn update_readiness(
417-
&self,
418-
ready_flags: Vec<u32>,
419-
epoll_events: &Vec<Weak<EpollEvent>>,
420-
) -> InterpResult<'tcx> {
421-
for event in epoll_events {
422-
// If the current epoll_event contains the flag that is signaled as ready, we add/update
423-
// the epoll_return entry in the ready list.
424-
if let Some(epoll_event) = event.upgrade() {
425-
if let Some(flags) = epoll_event.contains_flag(&ready_flags) {
426-
let weak_file_descriptor = epoll_event.weak_file_descriptor.clone();
427-
let epoll_key = (weak_file_descriptor, epoll_event.file_descriptor);
428-
// Retrieve the epoll return if it is already in the return list.
429-
let ready_list = &mut epoll_event.ready_list.borrow_mut();
430-
// Add a new epoll entry if it doesn't exist, or update the event mask if it exists.
431-
let epoll_return = EpollReturn::new(flags, epoll_event.data);
432-
let epoll_entry = ready_list.entry(epoll_key).or_insert(epoll_return);
433-
// The update here is bitwise or, so it will still be correct if we try to add
434-
// a flag that already exists.
435-
epoll_entry.update_events(flags);
436-
}
437-
}
438-
}
439-
Ok(())
440-
}
441-
442412
fn read(&mut self, fd: i32, buf: Pointer, count: u64) -> InterpResult<'tcx, i64> {
443413
let this = self.eval_context_mut();
444414

src/shims/unix/fs.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ impl FileDescription for FileHandle {
6060

6161
fn close<'tcx>(
6262
self: Box<Self>,
63-
_ecx: &mut MiriInterpCx<'tcx>,
6463
communicate_allowed: bool,
6564
) -> InterpResult<'tcx, io::Result<()>> {
6665
assert!(communicate_allowed, "isolation should have prevented even opening a file");

src/shims/unix/linux/epoll.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ impl FileDescription for Epoll {
8888

8989
fn close<'tcx>(
9090
self: Box<Self>,
91-
_ecx: &mut MiriInterpCx<'tcx>,
9291
_communicate_allowed: bool,
9392
) -> InterpResult<'tcx, io::Result<()>> {
9493
Ok(Ok(()))
@@ -215,8 +214,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
215214
interest_list.insert(epoll_key, event);
216215

217216
target_file_description.check_readiness(this).map(|events| {
218-
this.update_readiness(events, target_file_description.return_epoll_events()?)
219-
})??;
217+
target_file_description.update_readiness(
218+
events,
219+
target_file_description.return_epoll_events().unwrap(),
220+
)
221+
})?;
220222

221223
Ok(Scalar::from_i32(0))
222224
} else if op == epoll_ctl_del {

src/shims/unix/linux/eventfd.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::rc::Weak;
66

77
use rustc_target::abi::Endian;
88

9-
use crate::shims::unix::linux::epoll::EpollEvent;
9+
use crate::shims::unix::linux::epoll::{EpollEvent, EpollReturn};
1010
use crate::shims::unix::*;
1111
use crate::{concurrency::VClock, *};
1212

@@ -35,6 +35,30 @@ struct Event {
3535
epoll_events: Vec<Weak<EpollEvent>>,
3636
}
3737

38+
impl Event {
39+
/// Functions to update the ready list of an epoll_event.
40+
fn update_readiness(&self, ready_flags: Vec<u32>, epoll_events: &Vec<Weak<EpollEvent>>) {
41+
for event in epoll_events {
42+
// If the current epoll_event contains the flag that is signaled as ready, we add/update
43+
// the epoll_return entry in the ready list.
44+
if let Some(epoll_event) = event.upgrade() {
45+
if let Some(flags) = epoll_event.contains_flag(&ready_flags) {
46+
let weak_file_descriptor = epoll_event.weak_file_descriptor.clone();
47+
let epoll_key = (weak_file_descriptor, epoll_event.file_descriptor);
48+
// Retrieve the epoll return if it is already in the return list.
49+
let ready_list = &mut epoll_event.ready_list.borrow_mut();
50+
// Add a new epoll entry if it doesn't exist, or update the event mask if it exists.
51+
let epoll_return = EpollReturn::new(flags, epoll_event.data);
52+
let epoll_entry = ready_list.entry(epoll_key).or_insert(epoll_return);
53+
// The update here is bitwise or, so it will still be correct if we try to add
54+
// a flag that already exists.
55+
epoll_entry.update_events(flags);
56+
}
57+
}
58+
}
59+
}
60+
}
61+
3862
impl FileDescription for Event {
3963
fn name(&self) -> &'static str {
4064
"event"
@@ -62,7 +86,6 @@ impl FileDescription for Event {
6286
}
6387
fn close<'tcx>(
6488
self: Box<Self>,
65-
_ecx: &mut MiriInterpCx<'tcx>,
6689
_communicate_allowed: bool,
6790
) -> InterpResult<'tcx, io::Result<()>> {
6891
Ok(Ok(()))
@@ -98,7 +121,7 @@ impl FileDescription for Event {
98121
self.counter = 0;
99122
// When any of the event is happened, we check and update the status of all supported flags.
100123
self.check_readiness(ecx)
101-
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
124+
.map(|events| self.update_readiness(events, self.return_epoll_events().unwrap()))?;
102125
return Ok(Ok(U64_ARRAY_SIZE));
103126
}
104127
}
@@ -144,8 +167,9 @@ impl FileDescription for Event {
144167
}
145168
self.counter = new_count;
146169
// When any of the event is happened, we check and update the status of all supported flags.
147-
self.check_readiness(ecx)
148-
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
170+
self.check_readiness(ecx).map(|events| {
171+
self.update_readiness(events, self.return_epoll_events().unwrap())
172+
})?;
149173
}
150174
None | Some(u64::MAX) => {
151175
if self.is_nonblock {

src/shims/unix/socket.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::io::{Error, ErrorKind, Read};
55
use std::rc::{Rc, Weak};
66

77
use crate::shims::unix::fd::WeakFileDescriptor;
8+
use crate::shims::unix::linux::epoll::EpollReturn;
89
use crate::shims::unix::*;
910
use crate::{concurrency::VClock, *};
1011

@@ -37,6 +38,28 @@ impl SocketPair {
3738
fn peer_is_closed(&mut self) {
3839
self.peer_closed = true;
3940
}
41+
42+
/// Functions to update the ready list of an epoll_event.
43+
fn update_readiness(&self, ready_flags: Vec<u32>, epoll_events: &Vec<Weak<EpollEvent>>) {
44+
for event in epoll_events {
45+
// If the current epoll_event contains the flag that is signaled as ready, we add/update
46+
// the epoll_return entry in the ready list.
47+
if let Some(epoll_event) = event.upgrade() {
48+
if let Some(flags) = epoll_event.contains_flag(&ready_flags) {
49+
let weak_file_descriptor = epoll_event.weak_file_descriptor.clone();
50+
let epoll_key = (weak_file_descriptor, epoll_event.file_descriptor);
51+
// Retrieve the epoll return if it is already in the return list.
52+
let ready_list = &mut epoll_event.ready_list.borrow_mut();
53+
// Add a new epoll entry if it doesn't exist, or update the event mask if it exists.
54+
let epoll_return = EpollReturn::new(flags, epoll_event.data);
55+
let epoll_entry = ready_list.entry(epoll_key).or_insert(epoll_return);
56+
// The update here is bitwise or, so it will still be correct if we try to add
57+
// a flag that already exists.
58+
epoll_entry.update_events(flags);
59+
}
60+
}
61+
}
62+
}
4063
}
4164

4265
#[derive(Debug)]
@@ -91,7 +114,6 @@ impl FileDescription for SocketPair {
91114

92115
fn close<'tcx>(
93116
self: Box<Self>,
94-
ecx: &mut MiriInterpCx<'tcx>,
95117
_communicate_allowed: bool,
96118
) -> InterpResult<'tcx, io::Result<()>> {
97119
// This is used to signal socketfd of other side that there is no writer to its readbuf.
@@ -107,9 +129,9 @@ impl FileDescription for SocketPair {
107129
let peer_socketpair = binding.downcast_mut::<SocketPair>().unwrap();
108130
peer_socketpair.peer_is_closed();
109131
// When any of the event is happened, we check and update the status of all supported flags.
110-
peer_socketpair
111-
.check_readiness(ecx)
112-
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
132+
//peer_socketpair
133+
// .check_readiness(ecx)
134+
// .map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
113135
}
114136
}
115137
// TODO: invoke check readiness from other side
@@ -160,7 +182,7 @@ impl FileDescription for SocketPair {
160182
let actual_read_size = readbuf.buf.read(bytes).unwrap();
161183
// When any of the event is happened, we check and update the status of all supported flags.
162184
self.check_readiness(ecx)
163-
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
185+
.map(|events| self.update_readiness(events, self.return_epoll_events().unwrap()))?;
164186
return Ok(Ok(actual_read_size));
165187
}
166188

@@ -203,7 +225,7 @@ impl FileDescription for SocketPair {
203225
writebuf.buf.extend(&bytes[..actual_write_size]);
204226
// When any of the event is happened, we check and update the status of all supported flags.
205227
self.check_readiness(ecx)
206-
.map(|events| ecx.update_readiness(events, self.return_epoll_events()?))??;
228+
.map(|events| self.update_readiness(events, self.return_epoll_events().unwrap()))?;
207229
return Ok(Ok(actual_write_size));
208230
}
209231
}

0 commit comments

Comments
 (0)