mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-03 09:01:50 -05:00
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.
This commit is contained in:
parent
abfca5cb58
commit
0138a51a2c
3 changed files with 69 additions and 9 deletions
|
|
@ -148,6 +148,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,8 +183,59 @@ char *pa_win32_get_toplevel(HANDLE handle) {
|
|||
|
||||
#endif
|
||||
|
||||
static void set_nonblock(int fd, bool nonblock) {
|
||||
|
||||
#ifdef O_NONBLOCK
|
||||
int v, nv;
|
||||
pa_assert(fd >= 0);
|
||||
|
||||
pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
|
@ -188,17 +243,12 @@ void pa_make_fd_nonblock(int fd) {
|
|||
|
||||
pa_assert_se((v = fcntl(fd, F_GETFL)) >= 0);
|
||||
|
||||
if (!(v & O_NONBLOCK))
|
||||
pa_assert_se(fcntl(fd, F_SETFL, v|O_NONBLOCK) >= 0);
|
||||
return !!(v & O_NONBLOCK);
|
||||
|
||||
#elif defined(OS_IS_WIN32)
|
||||
u_long arg = 1;
|
||||
if (ioctlsocket(fd, FIONBIO, &arg) < 0) {
|
||||
pa_assert_se(WSAGetLastError() == WSAENOTSOCK);
|
||||
pa_log_warn("Only sockets can be made non-blocking!");
|
||||
}
|
||||
return !!FD_ISSET(fd, &nonblocking_fds);
|
||||
#else
|
||||
pa_log_warn("Non-blocking I/O not supported.!");
|
||||
return false;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue