File tree 3 files changed +12
-11
lines changed
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> {
433
433
Ok ( Scalar :: from_i32 ( num_of_events) )
434
434
}
435
435
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!
441
443
fn check_and_update_readiness ( & self , fd_ref : & FileDescriptionRef ) -> InterpResult < ' tcx , ( ) > {
442
444
let this = self . eval_context_ref ( ) ;
443
445
let id = fd_ref. get_id ( ) ;
Original file line number Diff line number Diff line change @@ -71,9 +71,9 @@ impl FileDescription for SocketPair {
71
71
} else {
72
72
// Peer FD has been closed.
73
73
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 .
77
77
epoll_ready_events. epollin = true ;
78
78
epoll_ready_events. epollout = true ;
79
79
}
@@ -86,9 +86,7 @@ impl FileDescription for SocketPair {
86
86
ecx : & mut MiriInterpCx < ' tcx > ,
87
87
) -> InterpResult < ' tcx , io:: Result < ( ) > > {
88
88
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.
92
90
ecx. check_and_update_readiness ( & peer_fd) ?;
93
91
}
94
92
Ok ( Ok ( ( ) ) )
Original file line number Diff line number Diff line change @@ -96,6 +96,7 @@ fn test_epoll_socketpair() {
96
96
assert_eq ! ( res, 0 ) ;
97
97
98
98
// 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.
99
100
let expected_event = u32:: try_from ( libc:: EPOLLRDHUP | libc:: EPOLLIN | libc:: EPOLLOUT ) . unwrap ( ) ;
100
101
let expected_value = u64:: try_from ( fds[ 1 ] ) . unwrap ( ) ;
101
102
assert ! ( check_epoll_wait:: <8 >( epfd, & [ ( expected_event, expected_value) ] ) ) ;
You can’t perform that action at this time.
0 commit comments