Skip to content

Commit 8821108

Browse files
committed
Auto merge of #3813 - tiif:epollfix, r=RalfJung
Testcase fix for epoll Fixes #3811 This PR: - Fixed the error in ``epoll_ctl_del`` test - Simplified the logic in ``epoll_ctl_mod`` test - Added a new test to check if flag that we don't register won't trigger notification (double negation sounds a bit confusing here, feel free to suggest a better one ;) ) - Use assert_eq(0) for epoll_ctl test
2 parents 6ac5bbb + 56eee8e commit 8821108

File tree

1 file changed

+65
-38
lines changed

1 file changed

+65
-38
lines changed

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

+65-38
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ fn main() {
1414
test_not_fully_closed_fd();
1515
test_closed_fd();
1616
test_two_epoll_instance();
17+
test_no_notification_for_unregister_flag();
1718
test_epoll_ctl_mod();
1819
test_epoll_ctl_del();
1920
test_pointer();
@@ -68,7 +69,7 @@ fn test_epoll_socketpair() {
6869
u64: u64::try_from(fds[1]).unwrap(),
6970
};
7071
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
71-
assert_ne!(res, -1);
72+
assert_eq!(res, 0);
7273

7374
// Check result from epoll_wait.
7475
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
@@ -99,6 +100,8 @@ fn test_epoll_socketpair() {
99100
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
100101
}
101102

103+
// This test first registers a file description with a flag that does not lead to notification,
104+
// then EPOLL_CTL_MOD to add another flag that will lead to notification.
102105
fn test_epoll_ctl_mod() {
103106
// Create an epoll instance.
104107
let epfd = unsafe { libc::epoll_create1(0) };
@@ -109,37 +112,27 @@ fn test_epoll_ctl_mod() {
109112
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
110113
assert_eq!(res, 0);
111114

112-
// Write to fd[0].
113-
let data = "abcde".as_bytes().as_ptr();
114-
let res = unsafe { libc::write(fds[0], data as *const libc::c_void, 5) };
115-
assert_eq!(res, 5);
116-
117-
// Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET.
118-
// (Not using checked cast as EPOLLET wraps around.)
119-
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() };
115+
// Register fd[1] with EPOLLIN|EPOLLET.
116+
let mut ev = libc::epoll_event {
117+
events: (libc::EPOLLIN | libc::EPOLLET) as _,
118+
u64: u64::try_from(fds[1]).unwrap(),
119+
};
120120
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
121-
assert_ne!(res, -1);
121+
assert_eq!(res, 0);
122122

123-
// Check result from epoll_wait.
124-
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
125-
let expected_value = u64::try_from(fds[1]).unwrap();
126-
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
123+
// Check result from epoll_wait. No notification would be returned.
124+
check_epoll_wait::<8>(epfd, &[]);
127125

128-
// Test EPOLLRDHUP.
126+
// Use EPOLL_CTL_MOD to change to EPOLLOUT flag.
129127
let mut ev = libc::epoll_event {
130-
events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET | libc::EPOLLRDHUP) as _,
128+
events: (libc::EPOLLOUT | libc::EPOLLET) as _,
131129
u64: u64::try_from(fds[1]).unwrap(),
132130
};
133131
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_MOD, fds[1], &mut ev) };
134-
assert_ne!(res, -1);
135-
136-
// Close the other side of the socketpair to invoke EPOLLRDHUP.
137-
let res = unsafe { libc::close(fds[0]) };
138132
assert_eq!(res, 0);
139133

140-
// Check result from epoll_wait.
141-
let expected_event =
142-
u32::try_from(libc::EPOLLRDHUP | libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLHUP).unwrap();
134+
// Check result from epoll_wait. EPOLLOUT notification is expected.
135+
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
143136
let expected_value = u64::try_from(fds[1]).unwrap();
144137
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
145138
}
@@ -162,10 +155,12 @@ fn test_epoll_ctl_del() {
162155
// Register fd[1] with EPOLLIN|EPOLLOUT|EPOLLET
163156
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() };
164157
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
165-
assert_ne!(res, -1);
158+
assert_eq!(res, 0);
166159

167160
// Test EPOLL_CTL_DEL.
168-
check_epoll_wait::<0>(epfd, &[]);
161+
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_DEL, fds[1], &mut ev) };
162+
assert_eq!(res, 0);
163+
check_epoll_wait::<8>(epfd, &[]);
169164
}
170165

171166
// This test is for one fd registered under two different epoll instance.
@@ -189,9 +184,9 @@ fn test_two_epoll_instance() {
189184
// Register one side of the socketpair with EPOLLIN | EPOLLOUT | EPOLLET.
190185
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fds[1]).unwrap() };
191186
let res = unsafe { libc::epoll_ctl(epfd1, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
192-
assert_ne!(res, -1);
187+
assert_eq!(res, 0);
193188
let res = unsafe { libc::epoll_ctl(epfd2, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
194-
assert_ne!(res, -1);
189+
assert_eq!(res, 0);
195190

196191
// Notification should be received from both instance of epoll.
197192
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
@@ -219,9 +214,9 @@ fn test_two_same_fd_in_same_epoll_instance() {
219214
// Register both fd to the same epoll instance.
220215
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: 5 as u64 };
221216
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
222-
assert_ne!(res, -1);
217+
assert_eq!(res, 0);
223218
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, newfd, &mut ev) };
224-
assert_ne!(res, -1);
219+
assert_eq!(res, 0);
225220

226221
// Write to the socketpair.
227222
let data = "abcde".as_bytes().as_ptr();
@@ -254,7 +249,7 @@ fn test_epoll_eventfd() {
254249
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
255250
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
256251
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
257-
assert_ne!(res, -1);
252+
assert_eq!(res, 0);
258253

259254
// Check result from epoll_wait.
260255
let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
@@ -277,7 +272,7 @@ fn test_pointer() {
277272
let mut ev =
278273
libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: data.expose_provenance() as u64 };
279274
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
280-
assert_ne!(res, -1);
275+
assert_eq!(res, 0);
281276
}
282277

283278
// When read/write happened on one side of the socketpair, only the other side will be notified.
@@ -294,10 +289,10 @@ fn test_epoll_socketpair_both_sides() {
294289
// Register both fd to the same epoll instance.
295290
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[0] as u64 };
296291
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) };
297-
assert_ne!(res, -1);
292+
assert_eq!(res, 0);
298293
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: fds[1] as u64 };
299294
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
300-
assert_ne!(res, -1);
295+
assert_eq!(res, 0);
301296

302297
// Write to fds[1].
303298
let data = "abcde".as_bytes().as_ptr();
@@ -340,7 +335,7 @@ fn test_closed_fd() {
340335
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
341336
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
342337
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
343-
assert_ne!(res, -1);
338+
assert_eq!(res, 0);
344339

345340
// Write to the eventfd instance.
346341
let sized_8_data: [u8; 8] = 1_u64.to_ne_bytes();
@@ -377,7 +372,7 @@ fn test_not_fully_closed_fd() {
377372
// Register eventfd with EPOLLIN | EPOLLOUT | EPOLLET
378373
let mut ev = libc::epoll_event { events: EPOLL_IN_OUT_ET, u64: u64::try_from(fd).unwrap() };
379374
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
380-
assert_ne!(res, -1);
375+
assert_eq!(res, 0);
381376

382377
// Close the original fd that being used to register with epoll.
383378
let res = unsafe { libc::close(fd) };
@@ -423,7 +418,7 @@ fn test_event_overwrite() {
423418
u64: u64::try_from(fd).unwrap(),
424419
};
425420
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fd, &mut ev) };
426-
assert_ne!(res, -1);
421+
assert_eq!(res, 0);
427422

428423
// Read from the eventfd instance.
429424
let mut buf: [u8; 8] = [0; 8];
@@ -454,13 +449,13 @@ fn test_socketpair_read() {
454449
u64: fds[0] as u64,
455450
};
456451
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[0], &mut ev) };
457-
assert_ne!(res, -1);
452+
assert_eq!(res, 0);
458453
let mut ev = libc::epoll_event {
459454
events: (libc::EPOLLIN | libc::EPOLLOUT | libc::EPOLLET) as _,
460455
u64: fds[1] as u64,
461456
};
462457
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
463-
assert_ne!(res, -1);
458+
assert_eq!(res, 0);
464459

465460
// Write 5 bytes to fds[1].
466461
let data = "abcde".as_bytes().as_ptr();
@@ -501,3 +496,35 @@ fn test_socketpair_read() {
501496
let expected_value = fds[1] as u64;
502497
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
503498
}
499+
500+
// This is to test whether flag that we don't register won't trigger notification.
501+
fn test_no_notification_for_unregister_flag() {
502+
// Create an epoll instance.
503+
let epfd = unsafe { libc::epoll_create1(0) };
504+
assert_ne!(epfd, -1);
505+
506+
// Create a socketpair instance.
507+
let mut fds = [-1, -1];
508+
let res = unsafe { libc::socketpair(libc::AF_UNIX, libc::SOCK_STREAM, 0, fds.as_mut_ptr()) };
509+
assert_eq!(res, 0);
510+
511+
// Register fd[0] with EPOLLOUT|EPOLLET.
512+
let mut ev = libc::epoll_event {
513+
events: (libc::EPOLLOUT | libc::EPOLLET) as _,
514+
u64: u64::try_from(fds[0]).unwrap(),
515+
};
516+
let res = unsafe { libc::epoll_ctl(epfd, libc::EPOLL_CTL_ADD, fds[1], &mut ev) };
517+
assert_eq!(res, 0);
518+
519+
// Write to fd[1].
520+
let data = "abcde".as_bytes().as_ptr();
521+
let res: i32 =
522+
unsafe { libc::write(fds[1], data as *const libc::c_void, 5).try_into().unwrap() };
523+
assert_eq!(res, 5);
524+
525+
// Check result from epoll_wait. Since we didn't register EPOLLIN flag, the notification won't
526+
// contain EPOLLIN even though fds[0] is now readable.
527+
let expected_event = u32::try_from(libc::EPOLLOUT).unwrap();
528+
let expected_value = u64::try_from(fds[0]).unwrap();
529+
check_epoll_wait::<8>(epfd, &[(expected_event, expected_value)]);
530+
}

0 commit comments

Comments
 (0)