diff options
| author | tiif <pekyuan@gmail.com> | 2024-08-25 17:15:19 +0800 |
|---|---|---|
| committer | tiif <pekyuan@gmail.com> | 2024-08-25 17:15:19 +0800 |
| commit | 0ed13eb48a6ea9a2757541bdf3c2cd1f906e1f69 (patch) | |
| tree | 6d24c753228c547654fb8e14c9cb3974817020aa /src/tools | |
| parent | 09993ce6d5a45384adc8cab709c5517fe60b9161 (diff) | |
| download | rust-0ed13eb48a6ea9a2757541bdf3c2cd1f906e1f69.tar.gz rust-0ed13eb48a6ea9a2757541bdf3c2cd1f906e1f69.zip | |
Add test for triggering notification after timeout
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs index 1a1d058b983..2a5d3dff07f 100644 --- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs +++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-blocking.rs @@ -11,6 +11,7 @@ use std::thread::spawn; fn main() { test_epoll_block_without_notification(); test_epoll_block_then_unblock(); + test_notification_after_timeout(); } // Using `as` cast since `EPOLLET` wraps around @@ -43,6 +44,8 @@ fn check_epoll_wait<const N: usize>( assert_eq!(data, expected_event.1, "got wrong data"); } } + +// This test allows epoll_wait to block, then unblock without notification. fn test_epoll_block_without_notification() { // Create an epoll instance. let epfd = unsafe { libc::epoll_create1(0) }; @@ -62,10 +65,11 @@ fn test_epoll_block_without_notification() { let expected_value = fd as u64; check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); - // epoll_wait before triggering notification so it will block then unblock. + // This epoll wait blocks, and timeout without notification. check_epoll_wait::<1>(epfd, &[], 5); } +// This test triggers notification and unblocks the epoll_wait before timeout. fn test_epoll_block_then_unblock() { // Create an epoll instance. let epfd = unsafe { libc::epoll_create1(0) }; @@ -98,3 +102,38 @@ fn test_epoll_block_then_unblock() { check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10); thread1.join().unwrap(); } + +// This test triggers a notification after epoll_wait times out. +fn test_notification_after_timeout() { + // Create an epoll instance. + let epfd = unsafe { libc::epoll_create1(0) }; + assert_ne!(epfd, -1); + + // Create a socketpair instance. + let mut fds = [-1, -1]; + let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) }; + assert_eq!(res, 0); + + // Register one side of the socketpair with epoll. + let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 }; + let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) }; + assert_eq!(res, 0); + + // epoll_wait to clear notification. + let expected_event = u32::try_from(libc::EPOLLOUT).unwrap(); + let expected_value = fds[0] as u64; + check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 0); + + // epoll_wait timeouts without notification. + check_epoll_wait::<1>(epfd, &[], 10); + + // Trigger epoll notification after timeout. + let data = "abcde".as_bytes().as_ptr(); + let res = unsafe { libc::write(fds[1], data as *const libc::c_void, 5) }; + assert_eq!(res, 5); + + // Check the result of the notification. + let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap(); + let expected_value = fds[0] as u64; + check_epoll_wait::<1>(epfd, &[(expected_event, expected_value)], 10); +} |
