poll: don't let select() block on Windows

We cannot let select() block as we won't wake up on the other
things that MsgWaitForMultipleObjects() can monitor.
This commit is contained in:
Pierre Ossman 2013-09-23 14:56:38 +02:00 committed by Tanu Kaskinen
parent 7776a42be4
commit f70ec2776a

View file

@ -350,8 +350,9 @@ int
pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
{
struct timeval tv;
struct timeval *ptv;
#ifndef WINDOWS_NATIVE
struct timeval *ptv;
fd_set rfds, wfds, efds;
int maxfd, rc;
nfds_t i;
@ -376,17 +377,6 @@ pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
}
# endif /* OPEN_MAX -- else, no check is needed */
# endif /* !_SC_OPEN_MAX */
#else /* WINDOWS_NATIVE*/
HANDLE hEvent;
WSANETWORKEVENTS ev;
HANDLE h, handle_array[FD_SETSIZE + 2];
DWORD ret, wait_timeout, nhandles;
fd_set rfds, wfds, xfds;
BOOL poll_again;
MSG msg;
int rc = 0;
nfds_t i;
#endif
/* EFAULT is not necessary to implement, but let's do it in the
simplest case. */
@ -418,7 +408,6 @@ pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
return -1;
}
#ifndef WINDOWS_NATIVE
/* create fd sets and determine max fd */
maxfd = -1;
FD_ZERO (&rfds);
@ -475,7 +464,16 @@ pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
}
return rc;
#else
#else /* WINDOWS_NATIVE*/
HANDLE hEvent;
WSANETWORKEVENTS ev;
HANDLE h, handle_array[FD_SETSIZE + 2];
DWORD ret, wait_timeout, nhandles;
fd_set rfds, wfds, xfds;
BOOL poll_again;
MSG msg;
int rc = 0;
nfds_t i;
hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
@ -534,19 +532,16 @@ restart:
handle_array[nhandles++] = h;
if (pfd[i].revents)
timeout = 0;
else
{
if (!ptv)
ptv = &tv;
/* tune down to 0.25s. But don't touch smaller timeouts */
if (ptv->tv_usec > 250*1000 || ptv->tv_sec > 0)
ptv->tv_usec = 250*1000;
ptv->tv_sec = 0;
}
}
}
if (select (0, &rfds, &wfds, &xfds, ptv) > 0)
/* We poll current status using select(). It cannot be used to check
anything but sockets, so we still have to wait in
MsgWaitForMultipleObjects(). But that in turn cannot check existing
state, so we can't remove this select(). */
/* FIXME: MSDN states that we cannot give empty fd_set:s. */
tv.tv_sec = tv.tv_usec = 0;
if (select (0, &rfds, &wfds, &xfds, &tv) > 0)
{
/* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
no need to call select again. */
@ -582,7 +577,7 @@ restart:
}
if (poll_again)
select (0, &rfds, &wfds, &xfds, ptv);
select (0, &rfds, &wfds, &xfds, &tv);
/* Place a sentinel at the end of the array. */
handle_array[nhandles] = NULL;