For systems which have a fcntl() implementation, we can simplify the
code which determines whether a file selector is valid in pa_poll().
The old code, which is harder to read and more expensive, stays around
for all platforms we need to emulate poll() for using select(), and
which don't provide fcntl(). IOW, for Windows.
On Mac OS X, however, the detection for bad fds via more select() calls
doesn't work, resulting in hung main loops, so the patch fixes a real
bug there.
#endif
#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
if ((ready == -1) && (errno == EBADF)) {
ready = 0;
+ maxfd = -1;
+
+#ifdef OS_IS_WIN32
+ /*
+ * Windows has no fcntl(), so we have to trick around with more
+ * select() calls to find out what went wrong
+ */
FD_ZERO (&rset);
FD_ZERO (&wset);
FD_ZERO (&xset);
- maxfd = -1;
-
for (f = fds; f < &fds[nfds]; ++f) {
if (f->fd != -1) {
fd_set sngl_rset, sngl_wset, sngl_xset;
}
}
+#else /* !OS_IS_WIN32 */
+
+ for (f = fds; f < &fds[nfds]; f++)
+ if (f->fd != -1) {
+ /* use fcntl() to find out whether the descriptor is valid */
+ if (fcntl(f->fd, F_GETFL) != -1) {
+ if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) {
+ maxfd = f->fd;
+ ready++;
+ }
+ } else {
+ FD_CLR(f->fd, &rset);
+ FD_CLR(f->fd, &wset);
+ FD_CLR(f->fd, &xset);
+ }
+ }
+
+#endif
+
if (ready) {
/* Linux alters the tv struct... but it shouldn't matter here ...
* as we're going to be a little bit out anyway as we've just eaten