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
This commit is contained in:
Josh Gao 2018-03-29 12:34:28 -07:00
parent fd7486fb42
commit 05fb45be17
2 changed files with 21 additions and 1 deletions

View file

@ -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) {

View file

@ -529,6 +529,7 @@ extern int adb_poll(adb_pollfd* fds, size_t nfds, int timeout) {
int skipped = 0;
std::vector<WSAPOLLFD> sockets;
std::vector<adb_pollfd*> 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;