summaryrefslogtreecommitdiffhomepage
path: root/test/syscalls/linux/poll.cc
diff options
context:
space:
mode:
authorBhasker Hariharan <bhaskerh@google.com>2021-03-24 12:08:24 -0700
committergVisor bot <gvisor-bot@google.com>2021-03-24 12:11:44 -0700
commite7ca2a51a89a8ff2c9f5adfdfa5b51be1b3faeb3 (patch)
tree1abf748d2755526978f560abb67f29b6f83496c7 /test/syscalls/linux/poll.cc
parent72ff6a1cac6ab35132b4f79b1149590e103e5291 (diff)
Add POLLRDNORM/POLLWRNORM support.
On Linux these are meant to be equivalent to POLLIN/POLLOUT. Rather than hack these on in sys_poll etc it felt cleaner to just cleanup the call sites to notify for both events. This is what linux does as well. Fixes #5544 PiperOrigin-RevId: 364859977
Diffstat (limited to 'test/syscalls/linux/poll.cc')
-rw-r--r--test/syscalls/linux/poll.cc79
1 files changed, 70 insertions, 9 deletions
diff --git a/test/syscalls/linux/poll.cc b/test/syscalls/linux/poll.cc
index 7a316427d..6f9a9498c 100644
--- a/test/syscalls/linux/poll.cc
+++ b/test/syscalls/linux/poll.cc
@@ -64,7 +64,7 @@ TEST_F(PollTest, NegativeTimeout_NoRandomSave) {
EXPECT_TRUE(TimerFired());
}
-TEST_F(PollTest, NonBlockingEventPOLLIN) {
+void NonBlockingReadableTest(int16_t mask) {
// Create a pipe.
int fds[2];
ASSERT_THAT(pipe(fds), SyscallSucceeds());
@@ -77,14 +77,24 @@ TEST_F(PollTest, NonBlockingEventPOLLIN) {
ASSERT_THAT(WriteFd(fd1.get(), s, strlen(s) + 1), SyscallSucceeds());
// Poll on the reader fd with POLLIN event.
- struct pollfd poll_fd = {fd0.get(), POLLIN, 0};
+ struct pollfd poll_fd = {fd0.get(), mask, 0};
EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, 0), SyscallSucceedsWithValue(1));
// Should trigger POLLIN event.
- EXPECT_EQ(poll_fd.revents & POLLIN, POLLIN);
+ EXPECT_EQ(poll_fd.revents & mask, mask);
}
-TEST_F(PollTest, BlockingEventPOLLIN) {
+TEST_F(PollTest, NonBlockingEventPOLLIN) { NonBlockingReadableTest(POLLIN); }
+
+TEST_F(PollTest, NonBlockingEventPOLLRDNORM) {
+ NonBlockingReadableTest(POLLRDNORM);
+}
+
+TEST_F(PollTest, NonBlockingEventPOLLRDNORM_POLLIN) {
+ NonBlockingReadableTest(POLLRDNORM | POLLIN);
+}
+
+void BlockingReadableTest(int16_t mask) {
// Create a pipe.
int fds[2];
ASSERT_THAT(pipe(fds), SyscallSucceeds());
@@ -94,15 +104,15 @@ TEST_F(PollTest, BlockingEventPOLLIN) {
// Start a blocking poll on the read fd.
absl::Notification notify;
- ScopedThread t([&fd0, &notify]() {
+ ScopedThread t([&fd0, &notify, &mask]() {
notify.Notify();
- // Poll on the reader fd with POLLIN event.
- struct pollfd poll_fd = {fd0.get(), POLLIN, 0};
+ // Poll on the reader fd with readable event.
+ struct pollfd poll_fd = {fd0.get(), mask, 0};
EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, -1), SyscallSucceedsWithValue(1));
- // Should trigger POLLIN event.
- EXPECT_EQ(poll_fd.revents & POLLIN, POLLIN);
+ // Should trigger readable event.
+ EXPECT_EQ(poll_fd.revents & mask, mask);
});
notify.WaitForNotification();
@@ -113,6 +123,57 @@ TEST_F(PollTest, BlockingEventPOLLIN) {
ASSERT_THAT(WriteFd(fd1.get(), s, strlen(s) + 1), SyscallSucceeds());
}
+TEST_F(PollTest, BlockingEventPOLLIN) { BlockingReadableTest(POLLIN); }
+
+TEST_F(PollTest, BlockingEventPOLLRDNORM) { BlockingReadableTest(POLLRDNORM); }
+
+TEST_F(PollTest, BlockingEventPOLLRDNORM_POLLIN) {
+ BlockingReadableTest(POLLRDNORM | POLLIN);
+}
+
+void WritableTest(int16_t mask, int timeout) {
+ // Create a pipe.
+ int fds[2];
+ ASSERT_THAT(pipe(fds), SyscallSucceeds());
+
+ FileDescriptor fd0(fds[0]);
+ FileDescriptor fd1(fds[1]);
+
+ // In a newly created pipe 2nd fd should be writable.
+
+ // Poll on second fd for a writable event.
+ struct pollfd poll_fd = {fd1.get(), mask, 0};
+ EXPECT_THAT(RetryEINTR(poll)(&poll_fd, 1, timeout),
+ SyscallSucceedsWithValue(1));
+
+ // Should trigger a writable event.
+ EXPECT_EQ(poll_fd.revents & mask, mask);
+}
+
+TEST_F(PollTest, NonBlockingEventPOLLOUT) {
+ WritableTest(POLLOUT, /*timeout=*/0);
+}
+
+TEST_F(PollTest, NonBlockingEventPOLLWRNORM) {
+ WritableTest(POLLWRNORM, /*timeout=*/0);
+}
+
+TEST_F(PollTest, NonBlockingEventPOLLWRNORM_POLLOUT) {
+ WritableTest(POLLWRNORM | POLLOUT, /*timeout=*/0);
+}
+
+TEST_F(PollTest, BlockingEventPOLLOUT) {
+ WritableTest(POLLOUT, /*timeout=*/-1);
+}
+
+TEST_F(PollTest, BlockingEventPOLLWRNORM) {
+ WritableTest(POLLWRNORM, /*timeout=*/-1);
+}
+
+TEST_F(PollTest, BlockingEventPOLLWRNORM_POLLOUT) {
+ WritableTest(POLLWRNORM | POLLOUT, /*timeout=*/-1);
+}
+
TEST_F(PollTest, NonBlockingEventPOLLHUP) {
// Create a pipe.
int fds[2];