Skip to content

Commit 0ed13eb

Browse files
committed
Add test for triggering notification after timeout
1 parent 09993ce commit 0ed13eb

File tree

1 file changed

+40
-1
lines changed

1 file changed

+40
-1
lines changed

src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use std::thread::spawn;
1111
fn main() {
1212
test_epoll_block_without_notification();
1313
test_epoll_block_then_unblock();
14+
test_notification_after_timeout();
1415
}
1516

1617
// Using `as` cast since `EPOLLET` wraps around
@@ -43,6 +44,8 @@ fn check_epoll_wait<const N: usize>(
4344
assert_eq!(data, expected_event.1, "got wrong data");
4445
}
4546
}
47+
48+
// This test allows epoll_wait to block, then unblock without notification.
4649
fn test_epoll_block_without_notification() {
4750
// Create an epoll instance.
4851
let epfd = unsafe { libc::epoll_create1(0) };
@@ -62,10 +65,11 @@ fn test_epoll_block_without_notification() {
6265
let expected_value = fd as u64;
6366
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0);
6467

65-
// epoll_wait before triggering notification so it will block then unblock.
68+
// This epoll wait blocks, and timeout without notification.
6669
check_epoll_wait::<1>(epfd, &[], 5);
6770
}
6871

72+
// This test triggers notification and unblocks the epoll_wait before timeout.
6973
fn test_epoll_block_then_unblock() {
7074
// Create an epoll instance.
7175
let epfd = unsafe { libc::epoll_create1(0) };
@@ -98,3 +102,38 @@ fn test_epoll_block_then_unblock() {
98102
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10);
99103
thread1.join().unwrap();
100104
}
105+
106+
// This test triggers a notification after epoll_wait times out.
107+
fn test_notification_after_timeout() {
108+
// Create an epoll instance.
109+
let epfd = unsafe { libc::epoll_create1(0) };
110+
assert_ne!(epfd, -1);
111+
112+
// Create a socketpair instance.
113+
let mut fds = [-1, -1];
114+
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
115+
assert_eq!(res, 0);
116+
117+
// Register one side of the socketpair with epoll.
118+
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 };
119+
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) };
120+
assert_eq!(res, 0);
121+
122+
// epoll_wait to clear notification.
123+
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
124+
let expected_value = fds[0] as u64;
125+
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0);
126+
127+
// epoll_wait timeouts without notification.
128+
check_epoll_wait::<1>(epfd, &[], 10);
129+
130+
// Trigger epoll notification after timeout.
131+
let data = "abcde".as_bytes().as_ptr();
132+
let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) };
133+
assert_eq!(res, 5);
134+
135+
// Check the result of the notification.
136+
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
137+
let expected_value = fds[0] as u64;
138+
check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10);
139+
}

0 commit comments

Comments
 (0)