[pulseaudio-commits] 2 commits - src/pulsecore

Tanu Kaskinen tanuk at kemper.freedesktop.org
Fri Nov 15 01:01:08 PST 2013


 src/pulsecore/core-util.c  |  100 +++++++++++++++++++++++++++------------------
 src/pulsecore/core-util.h  |    3 +
 src/pulsecore/poll-win32.c |    5 ++
 3 files changed, 69 insertions(+), 39 deletions(-)

New commits:
commit e7df7bcd76edf334422e11e859cfd8282d4a699b
Author: Pierre Ossman <ossman at cendio.se>
Date:   Fri Sep 20 10:13:41 2013 +0200

    Revert "core: Transparently handle non-blocking sockets on Windows"
    
    This reverts commit c327850d9e4479a0572b7baaf8dafd737586e5a1 as
    the workaround in that commit is no longer needed after the real
    bug has been fixed.
    
    Conflicts:
    	src/pulsecore/core-util.c

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index 49fcc0f..a2c3a39 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -154,8 +154,6 @@ static fd_set nonblocking_fds;
 
 #ifdef OS_IS_WIN32
 
-#include "poll.h"
-
 /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
 char *pa_win32_get_toplevel(HANDLE handle) {
     static char *toplevel = NULL;
@@ -420,26 +418,13 @@ ssize_t pa_read(int fd, void *buf, size_t count, int *type) {
 #ifdef OS_IS_WIN32
 
     if (!type || *type == 0) {
-        int err;
         ssize_t r;
 
-retry:
         if ((r = recv(fd, buf, count, 0)) >= 0)
             return r;
 
-        err = WSAGetLastError();
-        if (err != WSAENOTSOCK) {
-            /* transparently handle non-blocking sockets, by waiting
-             * for readiness */
-            if (err == WSAEWOULDBLOCK) {
-                struct pollfd pfd;
-                pfd.fd = fd;
-                pfd.events = POLLIN;
-                if (pa_poll(&pfd, 1, -1) >= 0) {
-                    goto retry;
-                }
-            }
-            errno = err;
+        if (WSAGetLastError() != WSAENOTSOCK) {
+            errno = WSAGetLastError();
             return r;
         }
 
@@ -465,11 +450,7 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
 
     if (!type || *type == 0) {
         ssize_t r;
-#ifdef OS_IS_WIN32
-        int err;
 
-retry:
-#endif
         for (;;) {
             if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
 
@@ -483,19 +464,8 @@ retry:
         }
 
 #ifdef OS_IS_WIN32
-        err = WSAGetLastError();
-        if (err != WSAENOTSOCK) {
-            /* transparently handle non-blocking sockets, by waiting
-             * for readiness */
-            if (err == WSAEWOULDBLOCK) {
-                struct pollfd pfd;
-                pfd.fd = fd;
-                pfd.events = POLLOUT;
-                if (pa_poll(&pfd, 1, -1) >= 0) {
-                    goto retry;
-                }
-            }
-            errno = err;
+        if (WSAGetLastError() != WSAENOTSOCK) {
+            errno = WSAGetLastError();
             return r;
         }
 #else

commit 0138a51a2ce9e5b20086ba5de342f96ba765368f
Author: Pierre Ossman <ossman at cendio.se>
Date:   Fri Sep 20 10:10:50 2013 +0200

    core: make sure win32 sockets remain blocking
    
    Commit 7e344b5 hade the side effect of forcing every socket to
    be non-blocking on Windows. This is because of a (documented)
    side effect of WSAEventSelect(). So we need to make sure to restore
    blocking behaviour afterwards for relevant sockets.

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index e925918..49fcc0f 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -149,6 +149,10 @@
 static pa_strlist *recorded_env = NULL;
 
 #ifdef OS_IS_WIN32
+static fd_set nonblocking_fds;
+#endif
+
+#ifdef OS_IS_WIN32
 
 #include "poll.h"
 
@@ -179,30 +183,76 @@ char *pa_win32_get_toplevel(HANDLE handle) {
 
 #endif
 
-/** Make a file descriptor nonblock. Doesn't do any error checking */
-void pa_make_fd_nonblock(int fd) {
+static void set_nonblock(int fd, bool nonblock) {
 
 #ifdef O_NONBLOCK
-    int v;
+    int v, nv;
     pa_assert(fd >= 0);
 
     pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
 
-    if (!(v & O_NONBLOCK))
+    if (nonblock)
+        nv = v | O_NONBLOCK;
+    else
+        nv = v & ~O_NONBLOCK;
+
+    if (v != nv)
         pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
 
 #elif defined(OS_IS_WIN32)
-    u_long arg = 1;
+    u_long arg;
+
+    if (nonblock)
+        arg = 1;
+    else
+        arg = 0;
+
     if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
         pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
         pa_log_warn("Only sockets can be made non-blocking!");
+        return;
     }
+
+    /* There is no method to query status, so we remember all fds */
+    if (nonblock)
+        FD_SET(fd, &nonblocking_fds);
+    else
+        FD_CLR(fd, &nonblocking_fds);
 #else
     pa_log_warn("Non-blocking I/O not supported.!");
 #endif
 
 }
 
+/** Make a file descriptor nonblock. Doesn't do any error checking */
+void pa_make_fd_nonblock(int fd) {
+    set_nonblock(fd, true);
+}
+
+/** Make a file descriptor blocking. Doesn't do any error checking */
+void pa_make_fd_block(int fd) {
+    set_nonblock(fd, false);
+}
+
+/** Query if a file descriptor is non-blocking */
+bool pa_is_fd_nonblock(int fd) {
+
+#ifdef O_NONBLOCK
+    int v;
+    pa_assert(fd >= 0);
+
+    pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
+
+    return !!(v & O_NONBLOCK);
+
+#elif defined(OS_IS_WIN32)
+    return !!FD_ISSET(fd, &nonblocking_fds);
+#else
+    return false;
+#endif
+
+}
+
 /* Set the FD_CLOEXEC flag for a fd */
 void pa_make_fd_cloexec(int fd) {
 
@@ -531,13 +581,15 @@ ssize_t pa_loop_write(int fd, const void*data, size_t size, int *type) {
     return ret;
 }
 
-/** Platform independent read function. Necessary since not all
+/** Platform independent close function. Necessary since not all
  * systems treat all file descriptors equal. */
 int pa_close(int fd) {
 
 #ifdef OS_IS_WIN32
     int ret;
 
+    FD_CLR(fd, &nonblocking_fds);
+
     if ((ret = closesocket(fd)) == 0)
         return 0;
 
diff --git a/src/pulsecore/core-util.h b/src/pulsecore/core-util.h
index e117e9f..e6cb261 100644
--- a/src/pulsecore/core-util.h
+++ b/src/pulsecore/core-util.h
@@ -57,6 +57,9 @@ struct timeval;
 #endif
 
 void pa_make_fd_nonblock(int fd);
+void pa_make_fd_block(int fd);
+bool pa_is_fd_nonblock(int fd);
+
 void pa_make_fd_cloexec(int fd);
 
 int pa_make_secure_dir(const char* dir, mode_t m, uid_t uid, gid_t gid, bool update_perms);
diff --git a/src/pulsecore/poll-win32.c b/src/pulsecore/poll-win32.c
index 4256ed7..4a70171 100644
--- a/src/pulsecore/poll-win32.c
+++ b/src/pulsecore/poll-win32.c
@@ -65,6 +65,8 @@ typedef unsigned long nfds_t;
 
 #include <time.h>
 
+#include <pulsecore/core-util.h>
+
 #ifndef INFTIM
 # define INFTIM (-1)
 #endif
@@ -602,6 +604,9 @@ restart:
           /* It's a socket.  */
           WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
           WSAEventSelect ((SOCKET) h, 0, 0);
+          /* Have to restore blocking as WSAEventSelect() clears it */
+          if (!pa_is_fd_nonblock(pfd[i].fd))
+            pa_make_fd_block(pfd[i].fd);
 
           /* If we're lucky, WSAEnumNetworkEvents already provided a way
              to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */



More information about the pulseaudio-commits mailing list