explain the behavior on closed peers
This commit is contained in:
parent
9184eb54ea
commit
883e4773b3
3 changed files with 12 additions and 11 deletions
|
@ -433,11 +433,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
Ok(Scalar::from_i32(num_of_events))
|
Ok(Scalar::from_i32(num_of_events))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For a specific file description, get its ready events and update
|
/// For a specific file description, get its ready events and update the corresponding ready
|
||||||
/// the corresponding ready list. This function is called whenever a file description
|
/// list. This function should be called whenever an event causes more bytes or an EOF to become
|
||||||
/// is registered with epoll, or the buffer it reads from / writes to changed.
|
/// newly readable from an FD, and whenever more bytes can be written to an FD or no more future
|
||||||
/// This *will* report an event if anyone is subscribed to it, without any further
|
/// writes are possible.
|
||||||
/// filtering, so do not call this function when an FD didn't have anything happen to it!
|
///
|
||||||
|
/// This *will* report an event if anyone is subscribed to it, without any further filtering, so
|
||||||
|
/// do not call this function when an FD didn't have anything happen to it!
|
||||||
fn check_and_update_readiness(&self, fd_ref: &FileDescriptionRef) -> InterpResult<'tcx, ()> {
|
fn check_and_update_readiness(&self, fd_ref: &FileDescriptionRef) -> InterpResult<'tcx, ()> {
|
||||||
let this = self.eval_context_ref();
|
let this = self.eval_context_ref();
|
||||||
let id = fd_ref.get_id();
|
let id = fd_ref.get_id();
|
||||||
|
|
|
@ -71,9 +71,9 @@ impl FileDescription for SocketPair {
|
||||||
} else {
|
} else {
|
||||||
// Peer FD has been closed.
|
// Peer FD has been closed.
|
||||||
epoll_ready_events.epollrdhup = true;
|
epoll_ready_events.epollrdhup = true;
|
||||||
// This is an edge case. Whenever epollrdhup is triggered, epollin and epollout will be
|
// Since the peer is closed, even if no data is available reads will return EOF and
|
||||||
// added even though there is no data in the buffer.
|
// writes will return EPIPE. In other words, they won't block, so we mark this as ready
|
||||||
// FIXME: Figure out why. This looks like a bug.
|
// for read and write.
|
||||||
epoll_ready_events.epollin = true;
|
epoll_ready_events.epollin = true;
|
||||||
epoll_ready_events.epollout = true;
|
epoll_ready_events.epollout = true;
|
||||||
}
|
}
|
||||||
|
@ -86,9 +86,7 @@ impl FileDescription for SocketPair {
|
||||||
ecx: &mut MiriInterpCx<'tcx>,
|
ecx: &mut MiriInterpCx<'tcx>,
|
||||||
) -> InterpResult<'tcx, io::Result<()>> {
|
) -> InterpResult<'tcx, io::Result<()>> {
|
||||||
if let Some(peer_fd) = self.peer_fd().upgrade() {
|
if let Some(peer_fd) = self.peer_fd().upgrade() {
|
||||||
// Notify peer fd that closed has happened.
|
// Notify peer fd that close has happened, since that can unblock reads and writes.
|
||||||
// When any of the events happened, we check and update the status of all supported events
|
|
||||||
// types of peer fd.
|
|
||||||
ecx.check_and_update_readiness(&peer_fd)?;
|
ecx.check_and_update_readiness(&peer_fd)?;
|
||||||
}
|
}
|
||||||
Ok(Ok(()))
|
Ok(Ok(()))
|
||||||
|
|
|
@ -96,6 +96,7 @@ fn test_epoll_socketpair() {
|
||||||
assert_eq!(res, 0);
|
assert_eq!(res, 0);
|
||||||
|
|
||||||
// Check result from epoll_wait.
|
// Check result from epoll_wait.
|
||||||
|
// We expect to get a read, write, HUP notification from the close since closing an FD always unblocks reads and writes on its peer.
|
||||||
let expected_event = u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
let expected_event = u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT).unwrap();
|
||||||
let expected_value = u64::try_from(fds[1]).unwrap();
|
let expected_value = u64::try_from(fds[1]).unwrap();
|
||||||
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
assert!(check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue