From 05fb45be17bbdde8977e442633f453d60724845f Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 29 Mar 2018 12:34:28 -0700 Subject: [PATCH] adb: fix FdeventTest.invalid_fd on Windows. Bail out immediately in our poll emulation if we have any invalid file descriptors, instead of actually calling WSAPoll (which might block forever). Test: wine adb_test.exe Change-Id: I06ccca305783ee7a1721b1585ddf73e022bd02d7 --- adb/sysdeps_test.cpp | 14 ++++++++++++++ adb/sysdeps_win32.cpp | 8 +++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/adb/sysdeps_test.cpp b/adb/sysdeps_test.cpp index fd1988252..79cebe6b5 100644 --- a/adb/sysdeps_test.cpp +++ b/adb/sysdeps_test.cpp @@ -121,10 +121,13 @@ TEST_F(sysdeps_poll, invalid_fd) { adb_pollfd pfd[3] = {}; pfd[0].fd = fds[0]; pfd[0].events = POLLRDNORM; + pfd[0].revents = ~0; pfd[1].fd = INT_MAX; pfd[1].events = POLLRDNORM; + pfd[1].revents = ~0; pfd[2].fd = fds[1]; pfd[2].events = POLLWRNORM; + pfd[2].revents = ~0; ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4)); @@ -136,6 +139,17 @@ TEST_F(sysdeps_poll, invalid_fd) { EXPECT_EQ(POLLRDNORM, pfd[0].revents); EXPECT_EQ(POLLNVAL, pfd[1].revents); EXPECT_EQ(POLLWRNORM, pfd[2].revents); + + // Make sure that we return immediately if an invalid FD is given. + pfd[0].fd = fds[0]; + pfd[0].events = POLLRDNORM; + pfd[0].revents = ~0; + pfd[1].fd = INT_MAX; + pfd[1].events = POLLRDNORM; + pfd[1].revents = ~0; + EXPECT_EQ(2, adb_poll(pfd, 2, -1)); + EXPECT_EQ(POLLRDNORM, pfd[0].revents); + EXPECT_EQ(POLLNVAL, pfd[1].revents); } TEST_F(sysdeps_poll, duplicate_fd) { diff --git a/adb/sysdeps_win32.cpp b/adb/sysdeps_win32.cpp index 62f4ac831..7d35fb67b 100644 --- a/adb/sysdeps_win32.cpp +++ b/adb/sysdeps_win32.cpp @@ -529,6 +529,7 @@ extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) { int skipped = 0; std::vector sockets; std::vector original; + for (size_t i = 0; i < nfds; ++i) { FH fh = _fh_from_int(fds[i].fd, __func__); if (!fh || !fh->used || fh->clazz != &_fh_socket_class) { @@ -549,6 +550,11 @@ extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) { return skipped; } + // If we have any invalid FDs in our FD set, make sure to return immediately. + if (skipped > 0) { + timeout = 0; + } + int result = WSAPoll(sockets.data(), sockets.size(), timeout); if (result == SOCKET_ERROR) { _socket_set_errno(WSAGetLastError()); @@ -560,7 +566,7 @@ extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) { original[i]->revents = sockets[i].revents; } - // WSAPoll appears to return the number of unique FDs with avaiable events, instead of how many + // WSAPoll appears to return the number of unique FDs with available events, instead of how many // of the pollfd elements have a non-zero revents field, which is what it and poll are specified // to do. Ignore its result and calculate the proper return value. result = 0;