]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/poll.c
Fix up according to Coding Style
[pulseaudio] / src / pulsecore / poll.c
index 3f9ace7c059ca9d74712cb56bdb02012e933a202..df4feb0117d8ffbc0eee1673b96455b832b3c53f 100644 (file)
@@ -1,25 +1,28 @@
-/* $Id$ */
 
 /***
-   Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
-   Copyright (C) 2005, Cendio AB.
-   This file is part of PulseAudio.
-   Based on work for the GNU C Library.
+  This file is part of PulseAudio.
+
+  Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
 
-   PulseAudio is free software; you can redistribute it and/or modify it
-   under the terms of the GNU Library General Public License as published
-   by the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
+  PulseAudio is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as published
+  by the Free Software Foundation; either version 2.1 of the License,
+  or (at your option) any later version.
 
-   PulseAudio is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
+  PulseAudio is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with PulseAudio; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+  USA.
+***/
 
-   You should have received a copy of the GNU Library General Public
-   License along with PulseAudio; If not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.
+/***
+   Based on work for the GNU C Library.
+   Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
 ***/
 
 /* Poll the file descriptors described by the NFDS structures starting at
 #include <config.h>
 #endif
 
+#ifdef HAVE_SYS_IOCTL_H
+#include <sys/ioctl.h>
+#endif
+
 #include <errno.h>
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #endif
 
-#include "winsock.h"
-
-#ifndef HAVE_SYS_POLL_H
-
+#include <pulsecore/socket.h>
 #include <pulsecore/core-util.h>
+#include <pulse/util.h>
 
 #include "poll.h"
 
-int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
+/* Mac OSX fails to implement poll() in a working way since 10.4. IOW, for
+ * several years. We need to enable a dirty workaround and emulate that call
+ * with select(), just like for Windows. sic! */
+
+#if !defined(HAVE_POLL_H) || defined(OS_IS_DARWIN)
+
+int pa_poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
     struct timeval tv;
     fd_set rset, wset, xset;
     struct pollfd *f;
     int ready;
     int maxfd = 0;
+#ifdef OS_IS_WIN32
     char data[64];
+#endif
 
     FD_ZERO (&rset);
     FD_ZERO (&wset);
@@ -92,9 +105,10 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
     tv.tv_sec = timeout / 1000;
     tv.tv_usec = (timeout % 1000) * 1000;
 
-    ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
+    ready = select((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
                     SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset,
                     SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv));
+
     if ((ready == -1) && (errno == EBADF)) {
         ready = 0;
 
@@ -146,7 +160,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
         /* 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
          * more than a couple of cpu cycles above */
-            ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
+            ready = select((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset,
                             SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset,
                             SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv));
         }
@@ -157,6 +171,8 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
 #endif
 
     if (ready > 0) {
+        int r;
+
         ready = 0;
         for (f = fds; f < &fds[nfds]; ++f) {
             f->revents = 0;
@@ -164,6 +180,18 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
                 if (FD_ISSET (f->fd, &rset)) {
                     /* support for POLLHUP.  An hung up descriptor does not
                        increase the return value! */
+#ifdef OS_IS_DARWIN
+                    /* There is a bug in Mac OS X that causes it to ignore MSG_PEEK
+                     * for some kinds of descriptors.  Detect if this descriptor is a
+                     * connected socket, a server socket, or something else using a
+                     * 0-byte recv, and use ioctl(2) to detect POLLHUP.  */
+                    r = recv(f->fd, NULL, 0, MSG_PEEK);
+                    if (r == 0 || (r < 0 && errno == ENOTSOCK))
+                        ioctl(f->fd, FIONREAD, &r);
+
+                    if (r == 0)
+                        f->revents |= POLLHUP;
+#else /* !OS_IS_DARWIN */
                     if (recv (f->fd, data, 64, MSG_PEEK) == -1) {
                         if (errno == ESHUTDOWN || errno == ECONNRESET ||
                             errno == ECONNABORTED || errno == ENETRESET) {
@@ -171,6 +199,7 @@ int poll (struct pollfd *fds, unsigned long int nfds, int timeout) {
                             f->revents |= POLLHUP;
                         }
                     }
+#endif
 
                     if (f->revents == 0)
                         f->revents |= POLLIN;