diff options
author | Thomas Martitz <kugel@rockbox.org> | 2012-08-20 23:50:37 +0200 |
---|---|---|
committer | Arun Raghavan <arun.raghavan@collabora.co.uk> | 2012-10-23 12:12:02 +0530 |
commit | c327850d9e4479a0572b7baaf8dafd737586e5a1 (patch) | |
tree | b292fbae65edbfe86d3887aebd680fb1b878f360 /src | |
parent | c1637652eaf3682dc2b5aa8c87b45552a8e1cf67 (diff) |
core: Transparently handle non-blocking sockets on Windows
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().
Diffstat (limited to 'src')
-rw-r--r-- | src/pulsecore/core-util.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/src/pulsecore/core-util.c b/src/pulsecore/core-util.c index 1e40ba0a6..710c9dc49 100644 --- a/src/pulsecore/core-util.c +++ b/src/pulsecore/core-util.c @@ -150,6 +150,8 @@ 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; @@ -368,13 +370,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; } @@ -400,7 +415,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) { @@ -414,8 +431,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 |