File tree Expand file tree Collapse file tree 3 files changed +12
-11
lines changed Expand file tree Collapse file tree 3 files changed +12
-11
lines changed Original file line number Diff line number Diff line change @@ -433,11 +433,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
433433 Ok ( Scalar :: from_i32 ( num_of_events) )
434434 }
435435
436- /// For a specific file description, get its ready events and update
437- /// the corresponding ready list. This function is called whenever a file description
438- /// is registered with epoll, or the buffer it reads from / writes to changed.
439- /// This *will* report an event if anyone is subscribed to it, without any further
440- /// filtering, so do not call this function when an FD didn't have anything happen to it!
436+ /// For a specific file description, get its ready events and update the corresponding ready
437+ /// list. This function should be called whenever an event causes more bytes or an EOF to become
438+ /// newly readable from an FD, and whenever more bytes can be written to an FD or no more future
439+ /// writes are possible.
440+ ///
441+ /// This *will* report an event if anyone is subscribed to it, without any further filtering, so
442+ /// do not call this function when an FD didn't have anything happen to it!
441443 fn check_and_update_readiness ( & self , fd_ref : & FileDescriptionRef ) -> InterpResult < ' tcx , ( ) > {
442444 let this = self . eval_context_ref ( ) ;
443445 let id = fd_ref. get_id ( ) ;
Original file line number Diff line number Diff line change @@ -71,9 +71,9 @@ impl FileDescription for SocketPair {
7171 } else {
7272 // Peer FD has been closed.
7373 epoll_ready_events. epollrdhup = true ;
74- // This is an edge case. Whenever epollrdhup is triggered, epollin and epollout will be
75- // added even though there is no data in the buffer.
76- // FIXME: Figure out why. This looks like a bug .
74+ // Since the peer is closed, even if no data is available reads will return EOF and
75+ // writes will return EPIPE. In other words, they won't block, so we mark this as ready
76+ // for read and write .
7777 epoll_ready_events. epollin = true ;
7878 epoll_ready_events. epollout = true ;
7979 }
@@ -86,9 +86,7 @@ impl FileDescription for SocketPair {
8686 ecx : & mut MiriInterpCx < ' tcx > ,
8787 ) -> InterpResult < ' tcx , io:: Result < ( ) > > {
8888 if let Some ( peer_fd) = self . peer_fd ( ) . upgrade ( ) {
89- // Notify peer fd that closed has happened.
90- // When any of the events happened, we check and update the status of all supported events
91- // types of peer fd.
89+ // Notify peer fd that close has happened, since that can unblock reads and writes.
9290 ecx. check_and_update_readiness ( & peer_fd) ?;
9391 }
9492 Ok ( Ok ( ( ) ) )
Original file line number Diff line number Diff line change @@ -96,6 +96,7 @@ fn test_epoll_socketpair() {
9696 assert_eq ! ( res, 0 ) ;
9797
9898 // Check result from epoll_wait.
99+ // We expect to get a read, write, HUP notification from the close since closing an FD always unblocks reads and writes on its peer.
99100 let expected_event = u32:: try_from ( libc:: EPOLLRDHUP | libc:: EPOLLIN | libc:: EPOLLOUT ) . unwrap ( ) ;
100101 let expected_value = u64:: try_from ( fds[ 1 ] ) . unwrap ( ) ;
101102 assert ! ( check_epoll_wait:: <8 >( epfd, & [ ( expected_event, expected_value) ] ) ) ;
You can’t perform that action at this time.
0 commit comments