mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-10-31 22:25:33 -04:00
Add function to "wake up", i.e. interrupt, a running poll(). This is needed
when having the poll() in a separate thread. git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@479 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
bbaf1543bd
commit
f77d5e14dc
2 changed files with 71 additions and 1 deletions
|
|
@ -91,6 +91,8 @@ struct pa_mainloop {
|
|||
|
||||
int deferred_pending;
|
||||
|
||||
int wakeup_pipe[2];
|
||||
|
||||
enum {
|
||||
STATE_PASSIVE,
|
||||
STATE_PREPARED,
|
||||
|
|
@ -115,6 +117,8 @@ static pa_io_event* mainloop_io_new(
|
|||
m = a->userdata;
|
||||
assert(a == &m->api);
|
||||
|
||||
pa_mainloop_wakeup(m);
|
||||
|
||||
e = pa_xmalloc(sizeof(pa_io_event));
|
||||
e->mainloop = m;
|
||||
e->dead = 0;
|
||||
|
|
@ -154,12 +158,17 @@ static pa_io_event* mainloop_io_new(
|
|||
static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
|
||||
assert(e && e->mainloop);
|
||||
|
||||
pa_mainloop_wakeup(e->mainloop);
|
||||
|
||||
e->events = events;
|
||||
e->mainloop->rebuild_pollfds = 1;
|
||||
}
|
||||
|
||||
static void mainloop_io_free(pa_io_event *e) {
|
||||
assert(e && e->mainloop);
|
||||
|
||||
pa_mainloop_wakeup(e->mainloop);
|
||||
|
||||
e->dead = e->mainloop->io_events_scan_dead = e->mainloop->rebuild_pollfds = 1;
|
||||
}
|
||||
|
||||
|
|
@ -229,6 +238,8 @@ static pa_time_event* mainloop_time_new(pa_mainloop_api*a, const struct timeval
|
|||
m = a->userdata;
|
||||
assert(a == &m->api);
|
||||
|
||||
pa_mainloop_wakeup(m);
|
||||
|
||||
e = pa_xmalloc(sizeof(pa_time_event));
|
||||
e->mainloop = m;
|
||||
e->dead = 0;
|
||||
|
|
@ -249,6 +260,8 @@ static pa_time_event* mainloop_time_new(pa_mainloop_api*a, const struct timeval
|
|||
static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
|
||||
assert(e);
|
||||
|
||||
pa_mainloop_wakeup(e->mainloop);
|
||||
|
||||
if (tv) {
|
||||
e->enabled = 1;
|
||||
e->timeval = *tv;
|
||||
|
|
@ -259,6 +272,8 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
|
|||
static void mainloop_time_free(pa_time_event *e) {
|
||||
assert(e);
|
||||
|
||||
pa_mainloop_wakeup(e->mainloop);
|
||||
|
||||
e->dead = e->mainloop->time_events_scan_dead = 1;
|
||||
}
|
||||
|
||||
|
|
@ -275,6 +290,8 @@ static void mainloop_quit(pa_mainloop_api*a, int retval) {
|
|||
m = a->userdata;
|
||||
assert(a == &m->api);
|
||||
|
||||
pa_mainloop_wakeup(m);
|
||||
|
||||
m->quit = 1;
|
||||
m->retval = retval;
|
||||
}
|
||||
|
|
@ -305,6 +322,19 @@ pa_mainloop *pa_mainloop_new(void) {
|
|||
|
||||
m = pa_xmalloc(sizeof(pa_mainloop));
|
||||
|
||||
#ifndef OS_ISWIN32
|
||||
if (pipe(m->wakeup_pipe) < 0) {
|
||||
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);
|
||||
m->time_events = pa_idxset_new(NULL, NULL);
|
||||
|
|
@ -386,6 +416,12 @@ void pa_mainloop_free(pa_mainloop* m) {
|
|||
pa_idxset_free(m->defer_events, NULL, NULL);
|
||||
|
||||
pa_xfree(m->pollfds);
|
||||
|
||||
if (m->wakeup_pipe[0] >= 0)
|
||||
close(m->wakeup_pipe[0]);
|
||||
if (m->wakeup_pipe[1] >= 0)
|
||||
close(m->wakeup_pipe[1]);
|
||||
|
||||
pa_xfree(m);
|
||||
}
|
||||
|
||||
|
|
@ -409,7 +445,7 @@ static void rebuild_pollfds(pa_mainloop *m) {
|
|||
uint32_t idx = PA_IDXSET_INVALID;
|
||||
unsigned l;
|
||||
|
||||
l = pa_idxset_size(m->io_events);
|
||||
l = pa_idxset_size(m->io_events) + 1;
|
||||
if (m->max_pollfds < l) {
|
||||
m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
|
||||
m->max_pollfds = l;
|
||||
|
|
@ -417,6 +453,15 @@ static void rebuild_pollfds(pa_mainloop *m) {
|
|||
|
||||
m->n_pollfds = 0;
|
||||
p = m->pollfds;
|
||||
|
||||
if (m->wakeup_pipe[0] >= 0) {
|
||||
m->pollfds[0].fd = m->wakeup_pipe[0];
|
||||
m->pollfds[0].events = POLLIN;
|
||||
m->pollfds[0].revents = 0;
|
||||
p++;
|
||||
m->n_pollfds++;
|
||||
}
|
||||
|
||||
for (e = pa_idxset_first(m->io_events, &idx); e; e = pa_idxset_next(m->io_events, &idx)) {
|
||||
if (e->dead) {
|
||||
e->pollfd = NULL;
|
||||
|
|
@ -558,11 +603,32 @@ static int dispatch_timeout(pa_mainloop *m) {
|
|||
return r;
|
||||
}
|
||||
|
||||
void pa_mainloop_wakeup(pa_mainloop *m) {
|
||||
char c = 'W';
|
||||
assert(m);
|
||||
|
||||
if (m->wakeup_pipe[1] >= 0)
|
||||
write(m->wakeup_pipe[1], &c, sizeof(c));
|
||||
}
|
||||
|
||||
static void clear_wakeup(pa_mainloop *m) {
|
||||
char c[10];
|
||||
|
||||
assert(m);
|
||||
|
||||
if (m->wakeup_pipe[0] < 0)
|
||||
return;
|
||||
|
||||
while (read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
|
||||
}
|
||||
|
||||
int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
|
||||
int dispatched = 0;
|
||||
|
||||
assert(m && (m->state == STATE_PASSIVE));
|
||||
|
||||
clear_wakeup(m);
|
||||
|
||||
scan_dead(m);
|
||||
|
||||
if (m->quit)
|
||||
|
|
@ -688,6 +754,7 @@ int pa_mainloop_run(pa_mainloop *m, int *retval) {
|
|||
|
||||
void pa_mainloop_quit(pa_mainloop *m, int r) {
|
||||
assert(m);
|
||||
pa_mainloop_wakeup(m);
|
||||
m->quit = r;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ int pa_mainloop_deferred_pending(pa_mainloop *m);
|
|||
/** Shutdown the main loop */
|
||||
void pa_mainloop_quit(pa_mainloop *m, int r);
|
||||
|
||||
/** Interrupt a running poll (for threaded systems) */
|
||||
void pa_mainloop_wakeup(pa_mainloop *m);
|
||||
|
||||
PA_C_DECL_END
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue