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().
This commit is contained in:
Thomas Martitz 2012-08-20 23:50:37 +02:00 committed by Arun Raghavan
parent c1637652ea
commit c327850d9e

View file

@ -150,6 +150,8 @@ static pa_strlist *recorded_env = NULL;
#ifdef OS_IS_WIN32 #ifdef OS_IS_WIN32
#include "poll.h"
/* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */ /* Returns the directory of the current DLL, with '/bin/' removed if it is the last component */
char *pa_win32_get_toplevel(HANDLE handle) { char *pa_win32_get_toplevel(HANDLE handle) {
static char *toplevel = NULL; 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 #ifdef OS_IS_WIN32
if (!type || *type == 0) { if (!type || *type == 0) {
int err;
ssize_t r; ssize_t r;
retry:
if ((r = recv(fd, buf, count, 0)) >= 0) if ((r = recv(fd, buf, count, 0)) >= 0)
return r; return r;
if (WSAGetLastError() != WSAENOTSOCK) { err = WSAGetLastError();
errno = 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; return r;
} }
@ -400,7 +415,9 @@ ssize_t pa_write(int fd, const void *buf, size_t count, int *type) {
if (!type || *type == 0) { if (!type || *type == 0) {
ssize_t r; ssize_t r;
int err;
retry:
for (;;) { for (;;) {
if ((r = send(fd, buf, count, MSG_NOSIGNAL)) < 0) { 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 #ifdef OS_IS_WIN32
if (WSAGetLastError() != WSAENOTSOCK) { err = WSAGetLastError();
errno = 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; return r;
} }
#else #else