4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
37 #ifdef HAVE_SYS_POLL_H
40 #include <pulsecore/poll.h>
44 #include <pulsecore/pipe.h>
47 #include <pulse/timeval.h>
48 #include <pulse/xmalloc.h>
50 #include <pulsecore/core-util.h>
51 #include <pulsecore/llist.h>
52 #include <pulsecore/log.h>
53 #include <pulsecore/core-error.h>
54 #include <pulsecore/winsock.h>
55 #include <pulsecore/macro.h>
60 pa_mainloop *mainloop;
64 pa_io_event_flags_t events;
65 struct pollfd *pollfd;
67 pa_io_event_cb_t callback;
69 pa_io_event_destroy_cb_t destroy_callback;
71 PA_LLIST_FIELDS(pa_io_event);
74 struct pa_time_event {
75 pa_mainloop *mainloop;
79 struct timeval timeval;
81 pa_time_event_cb_t callback;
83 pa_time_event_destroy_cb_t destroy_callback;
85 PA_LLIST_FIELDS(pa_time_event);
88 struct pa_defer_event {
89 pa_mainloop *mainloop;
94 pa_defer_event_cb_t callback;
96 pa_defer_event_destroy_cb_t destroy_callback;
98 PA_LLIST_FIELDS(pa_defer_event);
102 PA_LLIST_HEAD(pa_io_event, io_events);
103 PA_LLIST_HEAD(pa_time_event, time_events);
104 PA_LLIST_HEAD(pa_defer_event, defer_events);
106 int n_enabled_defer_events, n_enabled_time_events, n_io_events;
107 int io_events_please_scan, time_events_please_scan, defer_events_please_scan;
109 struct pollfd *pollfds;
110 unsigned max_pollfds, n_pollfds;
113 int prepared_timeout;
114 pa_time_event *cached_next_time_event;
120 int wakeup_pipe_type;
121 int wakeup_requested;
131 pa_poll_func poll_func;
132 void *poll_func_userdata;
136 static short map_flags_to_libc(pa_io_event_flags_t flags) {
138 (flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
139 (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
140 (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
141 (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0);
144 static pa_io_event_flags_t map_flags_from_libc(short flags) {
146 (flags & POLLIN ? PA_IO_EVENT_INPUT : 0) |
147 (flags & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
148 (flags & POLLERR ? PA_IO_EVENT_ERROR : 0) |
149 (flags & POLLHUP ? PA_IO_EVENT_HANGUP : 0);
153 static pa_io_event* mainloop_io_new(
156 pa_io_event_flags_t events,
157 pa_io_event_cb_t callback,
164 pa_assert(a->userdata);
169 pa_assert(a == &m->api);
171 e = pa_xnew(pa_io_event, 1);
179 e->callback = callback;
180 e->userdata = userdata;
181 e->destroy_callback = NULL;
194 if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
195 SELECT_TYPE_ARG5 &tv) == -1) &&
196 (WSAGetLastError() == WSAENOTSOCK)) {
197 pa_log_warn("WARNING: cannot monitor non-socket file descriptors.");
203 PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
204 m->rebuild_pollfds = 1;
207 pa_mainloop_wakeup(m);
212 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
216 if (e->events == events)
222 e->pollfd->events = map_flags_to_libc(events);
224 e->mainloop->rebuild_pollfds = 1;
226 pa_mainloop_wakeup(e->mainloop);
229 static void mainloop_io_free(pa_io_event *e) {
234 e->mainloop->io_events_please_scan ++;
236 e->mainloop->n_io_events --;
237 e->mainloop->rebuild_pollfds = 1;
239 pa_mainloop_wakeup(e->mainloop);
242 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
245 e->destroy_callback = callback;
249 static pa_defer_event* mainloop_defer_new(
251 pa_defer_event_cb_t callback,
258 pa_assert(a->userdata);
262 pa_assert(a == &m->api);
264 e = pa_xnew(pa_defer_event, 1);
269 m->n_enabled_defer_events++;
271 e->callback = callback;
272 e->userdata = userdata;
273 e->destroy_callback = NULL;
275 PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
277 pa_mainloop_wakeup(e->mainloop);
282 static void mainloop_defer_enable(pa_defer_event *e, int b) {
286 if (e->enabled && !b) {
287 pa_assert(e->mainloop->n_enabled_defer_events > 0);
288 e->mainloop->n_enabled_defer_events--;
289 } else if (!e->enabled && b) {
290 e->mainloop->n_enabled_defer_events++;
291 pa_mainloop_wakeup(e->mainloop);
297 static void mainloop_defer_free(pa_defer_event *e) {
302 e->mainloop->defer_events_please_scan ++;
305 pa_assert(e->mainloop->n_enabled_defer_events > 0);
306 e->mainloop->n_enabled_defer_events--;
311 static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
315 e->destroy_callback = callback;
319 static pa_time_event* mainloop_time_new(
321 const struct timeval *tv,
322 pa_time_event_cb_t callback,
329 pa_assert(a->userdata);
333 pa_assert(a == &m->api);
335 e = pa_xnew(pa_time_event, 1);
339 if ((e->enabled = !!tv)) {
342 m->n_enabled_time_events++;
344 if (m->cached_next_time_event) {
345 pa_assert(m->cached_next_time_event->enabled);
347 if (pa_timeval_cmp(tv, &m->cached_next_time_event->timeval) < 0)
348 m->cached_next_time_event = e;
352 e->callback = callback;
353 e->userdata = userdata;
354 e->destroy_callback = NULL;
356 PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
359 pa_mainloop_wakeup(m);
364 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
368 if (e->enabled && !tv) {
369 pa_assert(e->mainloop->n_enabled_time_events > 0);
370 e->mainloop->n_enabled_time_events--;
371 } else if (!e->enabled && tv)
372 e->mainloop->n_enabled_time_events++;
374 if ((e->enabled = !!tv)) {
376 pa_mainloop_wakeup(e->mainloop);
379 if (e->mainloop->cached_next_time_event && e->enabled) {
380 pa_assert(e->mainloop->cached_next_time_event->enabled);
382 if (pa_timeval_cmp(tv, &e->mainloop->cached_next_time_event->timeval) < 0)
383 e->mainloop->cached_next_time_event = e;
384 } else if (e->mainloop->cached_next_time_event == e)
385 e->mainloop->cached_next_time_event = NULL;
388 static void mainloop_time_free(pa_time_event *e) {
393 e->mainloop->time_events_please_scan ++;
396 pa_assert(e->mainloop->n_enabled_time_events > 0);
397 e->mainloop->n_enabled_time_events--;
401 if (e->mainloop->cached_next_time_event == e)
402 e->mainloop->cached_next_time_event = NULL;
404 /* no wakeup needed here. Think about it! */
407 static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
411 e->destroy_callback = callback;
416 static void mainloop_quit(pa_mainloop_api*a, int retval) {
420 pa_assert(a->userdata);
422 pa_assert(a == &m->api);
424 pa_mainloop_quit(m, retval);
427 static const pa_mainloop_api vtable = {
430 .io_new= mainloop_io_new,
431 .io_enable= mainloop_io_enable,
432 .io_free= mainloop_io_free,
433 .io_set_destroy= mainloop_io_set_destroy,
435 .time_new = mainloop_time_new,
436 .time_restart = mainloop_time_restart,
437 .time_free = mainloop_time_free,
438 .time_set_destroy = mainloop_time_set_destroy,
440 .defer_new = mainloop_defer_new,
441 .defer_enable = mainloop_defer_enable,
442 .defer_free = mainloop_defer_free,
443 .defer_set_destroy = mainloop_defer_set_destroy,
445 .quit = mainloop_quit,
448 pa_mainloop *pa_mainloop_new(void) {
451 m = pa_xnew(pa_mainloop, 1);
453 m->wakeup_pipe_type = 0;
454 if (pipe(m->wakeup_pipe) < 0) {
455 pa_log_error("ERROR: cannot create wakeup pipe");
460 pa_make_nonblock_fd(m->wakeup_pipe[0]);
461 pa_make_nonblock_fd(m->wakeup_pipe[1]);
462 pa_fd_set_cloexec(m->wakeup_pipe[0], 1);
463 pa_fd_set_cloexec(m->wakeup_pipe[1], 1);
464 m->wakeup_requested = 0;
466 PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
467 PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
468 PA_LLIST_HEAD_INIT(pa_defer_event, m->defer_events);
470 m->n_enabled_defer_events = m->n_enabled_time_events = m->n_io_events = 0;
471 m->io_events_please_scan = m->time_events_please_scan = m->defer_events_please_scan = 0;
473 m->cached_next_time_event = NULL;
474 m->prepared_timeout = 0;
477 m->max_pollfds = m->n_pollfds = 0;
478 m->rebuild_pollfds = 1;
480 m->quit = m->retval = 0;
485 m->state = STATE_PASSIVE;
488 m->poll_func_userdata = NULL;
489 m->poll_func_ret = -1;
494 static void cleanup_io_events(pa_mainloop *m, int force) {
499 pa_io_event *n = e->next;
501 if (!force && m->io_events_please_scan <= 0)
504 if (force || e->dead) {
505 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
508 pa_assert(m->io_events_please_scan > 0);
509 m->io_events_please_scan--;
512 if (e->destroy_callback)
513 e->destroy_callback(&m->api, e, e->userdata);
517 m->rebuild_pollfds = 1;
523 pa_assert(m->io_events_please_scan == 0);
526 static void cleanup_time_events(pa_mainloop *m, int force) {
531 pa_time_event *n = e->next;
533 if (!force && m->time_events_please_scan <= 0)
536 if (force || e->dead) {
537 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
540 pa_assert(m->time_events_please_scan > 0);
541 m->time_events_please_scan--;
544 if (!e->dead && e->enabled) {
545 pa_assert(m->n_enabled_time_events > 0);
546 m->n_enabled_time_events--;
550 if (e->destroy_callback)
551 e->destroy_callback(&m->api, e, e->userdata);
559 pa_assert(m->time_events_please_scan == 0);
562 static void cleanup_defer_events(pa_mainloop *m, int force) {
567 pa_defer_event *n = e->next;
569 if (!force && m->defer_events_please_scan <= 0)
572 if (force || e->dead) {
573 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
576 pa_assert(m->defer_events_please_scan > 0);
577 m->defer_events_please_scan--;
580 if (!e->dead && e->enabled) {
581 pa_assert(m->n_enabled_defer_events > 0);
582 m->n_enabled_defer_events--;
586 if (e->destroy_callback)
587 e->destroy_callback(&m->api, e, e->userdata);
595 pa_assert(m->defer_events_please_scan == 0);
599 void pa_mainloop_free(pa_mainloop* m) {
602 cleanup_io_events(m, 1);
603 cleanup_defer_events(m, 1);
604 cleanup_time_events(m, 1);
606 pa_xfree(m->pollfds);
608 if (m->wakeup_pipe[0] >= 0)
609 close(m->wakeup_pipe[0]);
610 if (m->wakeup_pipe[1] >= 0)
611 close(m->wakeup_pipe[1]);
616 static void scan_dead(pa_mainloop *m) {
619 if (m->io_events_please_scan)
620 cleanup_io_events(m, 0);
622 if (m->time_events_please_scan)
623 cleanup_time_events(m, 0);
625 if (m->defer_events_please_scan)
626 cleanup_defer_events(m, 0);
629 static void rebuild_pollfds(pa_mainloop *m) {
634 l = m->n_io_events + 1;
635 if (m->max_pollfds < l) {
637 m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
644 if (m->wakeup_pipe[0] >= 0) {
645 m->pollfds[0].fd = m->wakeup_pipe[0];
646 m->pollfds[0].events = POLLIN;
647 m->pollfds[0].revents = 0;
652 for (e = m->io_events; e; e = e->next) {
660 p->events = map_flags_to_libc(e->events);
667 m->rebuild_pollfds = 0;
670 static int dispatch_pollfds(pa_mainloop *m) {
674 pa_assert(m->poll_func_ret > 0);
676 for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) {
677 if (e->dead || !e->pollfd || !e->pollfd->revents)
680 pa_assert(e->pollfd->fd == e->fd && e->callback);
681 e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
682 e->pollfd->revents = 0;
691 static int dispatch_defer(pa_mainloop *m) {
695 if (m->n_enabled_defer_events <= 0)
698 for (e = m->defer_events; e && !m->quit; e = e->next) {
699 if (e->dead || !e->enabled)
702 pa_assert(e->callback);
703 e->callback(&m->api, e, e->userdata);
710 static pa_time_event* find_next_time_event(pa_mainloop *m) {
711 pa_time_event *t, *n = NULL;
714 if (m->cached_next_time_event)
715 return m->cached_next_time_event;
717 for (t = m->time_events; t; t = t->next) {
719 if (t->dead || !t->enabled)
722 if (!n || pa_timeval_cmp(&t->timeval, &n->timeval) < 0) {
725 /* Shortcut for tv = { 0, 0 } */
726 if (n->timeval.tv_sec <= 0)
731 m->cached_next_time_event = n;
735 static int calc_next_timeout(pa_mainloop *m) {
740 if (!m->n_enabled_time_events)
743 t = find_next_time_event(m);
746 if (t->timeval.tv_sec <= 0)
749 pa_gettimeofday(&now);
751 if (pa_timeval_cmp(&t->timeval, &now) <= 0)
754 usec = pa_timeval_diff(&t->timeval, &now);
755 return (int) (usec / 1000);
758 static int dispatch_timeout(pa_mainloop *m) {
764 if (m->n_enabled_time_events <= 0)
767 pa_gettimeofday(&now);
769 for (e = m->time_events; e && !m->quit; e = e->next) {
771 if (e->dead || !e->enabled)
774 if (pa_timeval_cmp(&e->timeval, &now) <= 0) {
775 pa_assert(e->callback);
777 /* Disable time event */
778 mainloop_time_restart(e, NULL);
780 e->callback(&m->api, e, &e->timeval, e->userdata);
789 void pa_mainloop_wakeup(pa_mainloop *m) {
793 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
794 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
795 m->wakeup_requested++;
799 static void clear_wakeup(pa_mainloop *m) {
804 if (m->wakeup_pipe[0] < 0)
807 if (m->wakeup_requested) {
808 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c));
809 m->wakeup_requested = 0;
813 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
815 pa_assert(m->state == STATE_PASSIVE);
823 if (m->n_enabled_defer_events <= 0) {
824 if (m->rebuild_pollfds)
827 m->prepared_timeout = calc_next_timeout(m);
828 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
829 m->prepared_timeout = timeout;
832 m->state = STATE_PREPARED;
836 m->state = STATE_QUIT;
840 int pa_mainloop_poll(pa_mainloop *m) {
842 pa_assert(m->state == STATE_PREPARED);
847 m->state = STATE_POLLING;
849 if (m->n_enabled_defer_events )
850 m->poll_func_ret = 0;
852 pa_assert(!m->rebuild_pollfds);
855 m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
857 m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
859 if (m->poll_func_ret < 0) {
861 m->poll_func_ret = 0;
863 pa_log("poll(): %s", pa_cstrerror(errno));
867 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
868 return m->poll_func_ret;
871 m->state = STATE_QUIT;
875 int pa_mainloop_dispatch(pa_mainloop *m) {
879 pa_assert(m->state == STATE_POLLED);
884 if (m->n_enabled_defer_events)
885 dispatched += dispatch_defer(m);
887 if (m->n_enabled_time_events)
888 dispatched += dispatch_timeout(m);
893 if (m->poll_func_ret > 0)
894 dispatched += dispatch_pollfds(m);
900 m->state = STATE_PASSIVE;
905 m->state = STATE_QUIT;
909 int pa_mainloop_get_retval(pa_mainloop *m) {
914 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
918 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
921 if ((r = pa_mainloop_poll(m)) < 0)
924 if ((r = pa_mainloop_dispatch(m)) < 0)
931 if ((r == -2) && retval)
932 *retval = pa_mainloop_get_retval(m);
936 int pa_mainloop_run(pa_mainloop *m, int *retval) {
939 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
949 void pa_mainloop_quit(pa_mainloop *m, int retval) {
954 pa_mainloop_wakeup(m);
957 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
962 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
965 m->poll_func = poll_func;
966 m->poll_func_userdata = userdata;