summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2012-08-20 23:50:37 +0200
committerArun Raghavan <arun.raghavan@collabora.co.uk>2012-10-23 12:12:02 +0530
commitc327850d9e4479a0572b7baaf8dafd737586e5a1 (patch)
treeb292fbae65edbfe86d3887aebd680fb1b878f360 /src
parentc1637652eaf3682dc2b5aa8c87b45552a8e1cf67 (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.c36
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