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) pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
{ {
struct timeval tv; struct timeval tv;
struct timeval *ptv;
#ifndef WINDOWS_NATIVE #ifndef WINDOWS_NATIVE
struct timeval *ptv;
fd_set rfds, wfds, efds; fd_set rfds, wfds, efds;
int maxfd, rc; int maxfd, rc;
nfds_t i; 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 /* OPEN_MAX -- else, no check is needed */
# endif /* !_SC_OPEN_MAX */ # 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 /* EFAULT is not necessary to implement, but let's do it in the
simplest case. */ simplest case. */
@ -418,7 +408,6 @@ pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
return -1; return -1;
} }
#ifndef WINDOWS_NATIVE
/* create fd sets and determine max fd */ /* create fd sets and determine max fd */
maxfd = -1; maxfd = -1;
FD_ZERO (&rfds); FD_ZERO (&rfds);
@ -475,7 +464,16 @@ pa_poll (struct pollfd *pfd, nfds_t nfd, int timeout)
} }
return rc; 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); hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
@ -534,19 +532,16 @@ restart:
handle_array[nhandles++] = h; handle_array[nhandles++] = h;
if (pfd[i].revents) if (pfd[i].revents)
timeout = 0; 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 /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
no need to call select again. */ no need to call select again. */
@ -582,7 +577,7 @@ restart:
} }
if (poll_again) if (poll_again)
select (0, &rfds, &wfds, &xfds, ptv); select (0, &rfds, &wfds, &xfds, &tv);
/* Place a sentinel at the end of the array. */ /* Place a sentinel at the end of the array. */
handle_array[nhandles] = NULL; handle_array[nhandles] = NULL;