[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