@@ -258,6 +258,34 @@ fn test_epoll_eventfd() {
258258 let expected_event = u32:: try_from ( libc:: EPOLLIN | libc:: EPOLLOUT ) . unwrap ( ) ;
259259 let expected_value = u64:: try_from ( fd) . unwrap ( ) ;
260260 check_epoll_wait :: < 8 > ( epfd, & [ ( expected_event, expected_value) ] ) ;
261+
262+ // Write to the eventfd again.
263+ let res = unsafe { libc_utils:: write_all ( fd, sized_8_data. as_ptr ( ) as * const libc:: c_void , 8 ) } ;
264+ assert_eq ! ( res, 8 ) ;
265+
266+ // This does not change the status, so we should get no event.
267+ // However, Linux performs a spurious wakeup.
268+ check_epoll_wait :: < 8 > ( epfd, & [ ( expected_event, expected_value) ] ) ;
269+
270+ // Read from the eventfd.
271+ let mut buf = [ 0u8 ; 8 ] ;
272+ let res = unsafe { libc_utils:: read_all ( fd, buf. as_mut_ptr ( ) . cast ( ) , 8 ) } ;
273+ assert_eq ! ( res, 8 ) ;
274+
275+ // This consumes the event, so the read status is gone. However, deactivation
276+ // does not trigger an event.
277+ // Still, we see a spurious wakeup.
278+ let expected_event = u32:: try_from ( libc:: EPOLLOUT ) . unwrap ( ) ;
279+ check_epoll_wait :: < 8 > ( epfd, & [ ( expected_event, expected_value) ] ) ;
280+
281+ // Write the maximum possible value.
282+ let sized_8_data: [ u8 ; 8 ] = ( u64:: MAX - 1 ) . to_ne_bytes ( ) ;
283+ let res = unsafe { libc_utils:: write_all ( fd, sized_8_data. as_ptr ( ) as * const libc:: c_void , 8 ) } ;
284+ assert_eq ! ( res, 8 ) ;
285+
286+ // This reactivates reads, therefore triggering an event. Writing is no longer possible.
287+ let expected_event = u32:: try_from ( libc:: EPOLLIN ) . unwrap ( ) ;
288+ check_epoll_wait :: < 8 > ( epfd, & [ ( expected_event, expected_value) ] ) ;
261289}
262290
263291// When read/write happened on one side of the socketpair, only the other side will be notified.
0 commit comments