[pulseaudio-discuss] [PATCH v3 4/6] Windows/pa_read, _write: Transparently handle non-blocking sockets.

Thomas Martitz kugel at rockbox.org
Mon Aug 20 15:04:17 PDT 2012


From: Thomas Martitz <kuge at rockbox.org>

On Windows, fdsem.c:flush() fails because sockets are set to non-blocking
mode, since pa_read() returns -1 (and errno == EWOULDBLOCK). I guess pa_read()
is expected to block in this case so make it actually block by calling poll().
---
 src/pulsecore/core-util.c |   35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c
index e6ba46a..6f8557f 100644
--- a/src/pulsecore/core-util.c
+++ b/src/pulsecore/core-util.c
@@ -150,6 +150,7 @@ static pa_strlist *recorded_env = NULL;
 
 #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;
@@ -353,13 +354,26 @@ 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;
 
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        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;
             return r;
         }
 
@@ -385,7 +399,9 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
 
     if (!type || *type == 0) {
         ssize_t r;
+        int err;
 
+retry:
         for (;;) {
             if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) {
 
@@ -399,8 +415,19 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
         }
 
 #ifdef OS_IS_WIN32
-        if (WSAGetLastError() != WSAENOTSOCK) {
-            errno = WSAGetLastError();
+        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;
             return r;
         }
 #else
-- 
1.7.10.4



More information about the pulseaudio-discuss mailing list