mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-11 13:30:02 -05:00
Handle pipes on platforms where they are non-existant of broken.
We do this by creating a TCP socket pair instead of a normal pipe. Since Windows isn't UNIX-y enough to support read()/write() on sockets, we also need a wrapper to handle read() vs recv() and write() vs send(). git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@840 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
12d4b5d952
commit
48d66cd5e8
9 changed files with 249 additions and 107 deletions
|
|
@ -59,25 +59,17 @@ struct pa_signal_event {
|
|||
static pa_mainloop_api *api = NULL;
|
||||
static int signal_pipe[2] = { -1, -1 };
|
||||
static pa_io_event* io_event = NULL;
|
||||
static pa_time_event *time_event = NULL;
|
||||
static pa_signal_event *signals = NULL;
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
static unsigned int waiting_signals = 0;
|
||||
static CRITICAL_SECTION crit;
|
||||
#endif
|
||||
|
||||
static void signal_handler(int sig) {
|
||||
int result;
|
||||
#ifndef HAVE_SIGACTION
|
||||
signal(sig, signal_handler);
|
||||
#endif
|
||||
write(signal_pipe[1], &sig, sizeof(sig));
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
EnterCriticalSection(&crit);
|
||||
waiting_signals++;
|
||||
LeaveCriticalSection(&crit);
|
||||
#endif
|
||||
pa_log(__FILE__": Got signal %d", sig);
|
||||
result = pa_write(signal_pipe[1], &sig, sizeof(sig));
|
||||
if (result != sizeof(sig))
|
||||
pa_log(__FILE__": Bad write (%d, %d)", result, WSAGetLastError());
|
||||
}
|
||||
|
||||
static void dispatch(pa_mainloop_api*a, int sig) {
|
||||
|
|
@ -91,46 +83,14 @@ static void dispatch(pa_mainloop_api*a, int sig) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
static void timer(pa_mainloop_api*a, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, PA_GCC_UNUSED void *userdata) {
|
||||
ssize_t r;
|
||||
int sig;
|
||||
unsigned int sigs;
|
||||
struct timeval tvnext;
|
||||
|
||||
EnterCriticalSection(&crit);
|
||||
sigs = waiting_signals;
|
||||
waiting_signals = 0;
|
||||
LeaveCriticalSection(&crit);
|
||||
|
||||
while (sigs) {
|
||||
if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
|
||||
pa_log(__FILE__": read(): %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (r != sizeof(sig)) {
|
||||
pa_log(__FILE__": short read()");
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(a, sig);
|
||||
|
||||
sigs--;
|
||||
}
|
||||
|
||||
pa_timeval_add(pa_gettimeofday(&tvnext), 100000);
|
||||
a->time_restart(e, &tvnext);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags_t f, PA_GCC_UNUSED void *userdata) {
|
||||
ssize_t r;
|
||||
int sig;
|
||||
assert(a && e && f == PA_IO_EVENT_INPUT && e == io_event && fd == signal_pipe[0]);
|
||||
|
||||
|
||||
if ((r = read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
|
||||
pa_log(__FILE__": Signal pipe callback");
|
||||
|
||||
if ((r = pa_read(signal_pipe[0], &sig, sizeof(sig))) < 0) {
|
||||
if (errno == EAGAIN)
|
||||
return;
|
||||
|
||||
|
|
@ -147,17 +107,10 @@ static void callback(pa_mainloop_api*a, pa_io_event*e, int fd, pa_io_event_flags
|
|||
}
|
||||
|
||||
int pa_signal_init(pa_mainloop_api *a) {
|
||||
#ifdef OS_IS_WIN32
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event && !time_event);
|
||||
assert(!api && a && signal_pipe[0] == -1 && signal_pipe[1] == -1 && !io_event);
|
||||
|
||||
#ifdef OS_IS_WIN32
|
||||
if (_pipe(signal_pipe, 200, _O_BINARY) < 0) {
|
||||
#else
|
||||
if (pipe(signal_pipe) < 0) {
|
||||
#endif
|
||||
pa_log(__FILE__": pipe() failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -169,34 +122,20 @@ int pa_signal_init(pa_mainloop_api *a) {
|
|||
|
||||
api = a;
|
||||
|
||||
#ifndef OS_IS_WIN32
|
||||
io_event = api->io_new(api, signal_pipe[0], PA_IO_EVENT_INPUT, callback, NULL);
|
||||
assert(io_event);
|
||||
#else
|
||||
time_event = api->time_new(api, pa_gettimeofday(&tv), timer, NULL);
|
||||
assert(time_event);
|
||||
|
||||
InitializeCriticalSection(&crit);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pa_signal_done(void) {
|
||||
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && (io_event || time_event));
|
||||
assert(api && signal_pipe[0] >= 0 && signal_pipe[1] >= 0 && io_event);
|
||||
|
||||
while (signals)
|
||||
pa_signal_free(signals);
|
||||
|
||||
#ifndef OS_IS_WIN32
|
||||
api->io_free(io_event);
|
||||
io_event = NULL;
|
||||
#else
|
||||
api->time_free(time_event);
|
||||
time_event = NULL;
|
||||
|
||||
DeleteCriticalSection(&crit);
|
||||
#endif
|
||||
|
||||
close(signal_pipe[0]);
|
||||
close(signal_pipe[1]);
|
||||
|
|
|
|||
|
|
@ -40,6 +40,10 @@
|
|||
|
||||
#include "../polypcore/winsock.h"
|
||||
|
||||
#ifndef HAVE_PIPE
|
||||
#include "../polypcore/pipe.h"
|
||||
#endif
|
||||
|
||||
#include <polypcore/util.h>
|
||||
#include <polypcore/idxset.h>
|
||||
#include <polypcore/xmalloc.h>
|
||||
|
|
@ -330,18 +334,14 @@ pa_mainloop *pa_mainloop_new(void) {
|
|||
|
||||
m = pa_xmalloc(sizeof(pa_mainloop));
|
||||
|
||||
#ifndef OS_IS_WIN32
|
||||
if (pipe(m->wakeup_pipe) < 0) {
|
||||
pa_log_error(__FILE__": ERROR: cannot create wakeup pipe");
|
||||
pa_xfree(m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pa_make_nonblock_fd(m->wakeup_pipe[0]);
|
||||
pa_make_nonblock_fd(m->wakeup_pipe[1]);
|
||||
#else
|
||||
m->wakeup_pipe[0] = -1;
|
||||
m->wakeup_pipe[1] = -1;
|
||||
#endif
|
||||
|
||||
m->io_events = pa_idxset_new(NULL, NULL);
|
||||
m->defer_events = pa_idxset_new(NULL, NULL);
|
||||
|
|
@ -622,7 +622,7 @@ void pa_mainloop_wakeup(pa_mainloop *m) {
|
|||
assert(m);
|
||||
|
||||
if (m->wakeup_pipe[1] >= 0)
|
||||
write(m->wakeup_pipe[1], &c, sizeof(c));
|
||||
pa_write(m->wakeup_pipe[1], &c, sizeof(c));
|
||||
}
|
||||
|
||||
static void clear_wakeup(pa_mainloop *m) {
|
||||
|
|
@ -633,7 +633,7 @@ static void clear_wakeup(pa_mainloop *m) {
|
|||
if (m->wakeup_pipe[0] < 0)
|
||||
return;
|
||||
|
||||
while (read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
|
||||
while (pa_read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
|
||||
}
|
||||
|
||||
int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue