rtclock: enable rtclock for our own mainloop implementations
[pulseaudio-mirror.git] / src / pulse / mainloop.c
blobc418d10861807317c062b761a9c5658401181886
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
7 PulseAudio is free software; you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 2.1 of the License,
10 or (at your option) any later version.
12 PulseAudio is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 USA.
21 ***/
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
27 #include <stdio.h>
28 #include <signal.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <errno.h>
35 #ifdef HAVE_POLL_H
36 #include <poll.h>
37 #else
38 #include <pulsecore/poll.h>
39 #endif
41 #ifndef HAVE_PIPE
42 #include <pulsecore/pipe.h>
43 #endif
45 #include <pulse/i18n.h>
46 #include <pulse/rtclock.h>
47 #include <pulse/timeval.h>
48 #include <pulse/xmalloc.h>
50 #include <pulsecore/core-rtclock.h>
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/llist.h>
53 #include <pulsecore/log.h>
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/winsock.h>
56 #include <pulsecore/macro.h>
58 #include "mainloop.h"
59 #include "internal.h"
61 struct pa_io_event {
62 pa_mainloop *mainloop;
63 pa_bool_t dead:1;
65 int fd;
66 pa_io_event_flags_t events;
67 struct pollfd *pollfd;
69 pa_io_event_cb_t callback;
70 void *userdata;
71 pa_io_event_destroy_cb_t destroy_callback;
73 PA_LLIST_FIELDS(pa_io_event);
76 struct pa_time_event {
77 pa_mainloop *mainloop;
78 pa_bool_t dead:1;
80 pa_bool_t enabled:1;
81 pa_usec_t time;
83 pa_time_event_cb_t callback;
84 void *userdata;
85 pa_time_event_destroy_cb_t destroy_callback;
87 PA_LLIST_FIELDS(pa_time_event);
90 struct pa_defer_event {
91 pa_mainloop *mainloop;
92 pa_bool_t dead:1;
94 pa_bool_t enabled:1;
96 pa_defer_event_cb_t callback;
97 void *userdata;
98 pa_defer_event_destroy_cb_t destroy_callback;
100 PA_LLIST_FIELDS(pa_defer_event);
103 struct pa_mainloop {
104 PA_LLIST_HEAD(pa_io_event, io_events);
105 PA_LLIST_HEAD(pa_time_event, time_events);
106 PA_LLIST_HEAD(pa_defer_event, defer_events);
108 unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
109 unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
111 pa_bool_t rebuild_pollfds:1;
112 struct pollfd *pollfds;
113 unsigned max_pollfds, n_pollfds;
115 int prepared_timeout;
116 pa_time_event *cached_next_time_event;
118 pa_mainloop_api api;
120 int retval;
121 pa_bool_t quit:1;
123 pa_bool_t wakeup_requested:1;
124 int wakeup_pipe[2];
125 int wakeup_pipe_type;
127 enum {
128 STATE_PASSIVE,
129 STATE_PREPARED,
130 STATE_POLLING,
131 STATE_POLLED,
132 STATE_QUIT
133 } state;
135 pa_poll_func poll_func;
136 void *poll_func_userdata;
137 int poll_func_ret;
140 static short map_flags_to_libc(pa_io_event_flags_t flags) {
141 return (short)
142 ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
143 (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
144 (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
145 (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
148 static pa_io_event_flags_t map_flags_from_libc(short flags) {
149 return
150 (flags & POLLIN ? PA_IO_EVENT_INPUT : 0) |
151 (flags & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
152 (flags & POLLERR ? PA_IO_EVENT_ERROR : 0) |
153 (flags & POLLHUP ? PA_IO_EVENT_HANGUP : 0);
156 /* IO events */
157 static pa_io_event* mainloop_io_new(
158 pa_mainloop_api*a,
159 int fd,
160 pa_io_event_flags_t events,
161 pa_io_event_cb_t callback,
162 void *userdata) {
164 pa_mainloop *m;
165 pa_io_event *e;
167 pa_assert(a);
168 pa_assert(a->userdata);
169 pa_assert(fd >= 0);
170 pa_assert(callback);
172 m = a->userdata;
173 pa_assert(a == &m->api);
175 e = pa_xnew(pa_io_event, 1);
176 e->mainloop = m;
177 e->dead = FALSE;
179 e->fd = fd;
180 e->events = events;
181 e->pollfd = NULL;
183 e->callback = callback;
184 e->userdata = userdata;
185 e->destroy_callback = NULL;
187 #ifdef OS_IS_WIN32
189 fd_set xset;
190 struct timeval tv;
192 tv.tv_sec = 0;
193 tv.tv_usec = 0;
195 FD_ZERO (&xset);
196 FD_SET (fd, &xset);
198 if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
199 SELECT_TYPE_ARG5 &tv) == -1) &&
200 (WSAGetLastError() == WSAENOTSOCK)) {
201 pa_log_warn("Cannot monitor non-socket file descriptors.");
202 e->dead = TRUE;
205 #endif
207 PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
208 m->rebuild_pollfds = TRUE;
209 m->n_io_events ++;
211 pa_mainloop_wakeup(m);
213 return e;
216 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
217 pa_assert(e);
218 pa_assert(!e->dead);
220 if (e->events == events)
221 return;
223 e->events = events;
225 if (e->pollfd)
226 e->pollfd->events = map_flags_to_libc(events);
227 else
228 e->mainloop->rebuild_pollfds = TRUE;
230 pa_mainloop_wakeup(e->mainloop);
233 static void mainloop_io_free(pa_io_event *e) {
234 pa_assert(e);
235 pa_assert(!e->dead);
237 e->dead = TRUE;
238 e->mainloop->io_events_please_scan ++;
240 e->mainloop->n_io_events --;
241 e->mainloop->rebuild_pollfds = TRUE;
243 pa_mainloop_wakeup(e->mainloop);
246 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
247 pa_assert(e);
249 e->destroy_callback = callback;
252 /* Defer events */
253 static pa_defer_event* mainloop_defer_new(
254 pa_mainloop_api*a,
255 pa_defer_event_cb_t callback,
256 void *userdata) {
258 pa_mainloop *m;
259 pa_defer_event *e;
261 pa_assert(a);
262 pa_assert(a->userdata);
263 pa_assert(callback);
265 m = a->userdata;
266 pa_assert(a == &m->api);
268 e = pa_xnew(pa_defer_event, 1);
269 e->mainloop = m;
270 e->dead = FALSE;
272 e->enabled = TRUE;
273 m->n_enabled_defer_events++;
275 e->callback = callback;
276 e->userdata = userdata;
277 e->destroy_callback = NULL;
279 PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
281 pa_mainloop_wakeup(e->mainloop);
283 return e;
286 static void mainloop_defer_enable(pa_defer_event *e, int b) {
287 pa_assert(e);
288 pa_assert(!e->dead);
290 if (e->enabled && !b) {
291 pa_assert(e->mainloop->n_enabled_defer_events > 0);
292 e->mainloop->n_enabled_defer_events--;
293 } else if (!e->enabled && b) {
294 e->mainloop->n_enabled_defer_events++;
295 pa_mainloop_wakeup(e->mainloop);
298 e->enabled = b;
301 static void mainloop_defer_free(pa_defer_event *e) {
302 pa_assert(e);
303 pa_assert(!e->dead);
305 e->dead = TRUE;
306 e->mainloop->defer_events_please_scan ++;
308 if (e->enabled) {
309 pa_assert(e->mainloop->n_enabled_defer_events > 0);
310 e->mainloop->n_enabled_defer_events--;
311 e->enabled = FALSE;
315 static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
316 pa_assert(e);
317 pa_assert(!e->dead);
319 e->destroy_callback = callback;
322 /* Time events */
323 static pa_usec_t timeval_load(const struct timeval *tv) {
324 pa_bool_t is_rtclock;
325 struct timeval ttv;
327 if (!tv)
328 return PA_USEC_INVALID;
330 ttv = *tv;
331 is_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
332 ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
334 if (!is_rtclock)
335 pa_rtclock_from_wallclock(&ttv);
337 return pa_timeval_load(&ttv);
340 static pa_time_event* mainloop_time_new(
341 pa_mainloop_api*a,
342 const struct timeval *tv,
343 pa_time_event_cb_t callback,
344 void *userdata) {
346 pa_mainloop *m;
347 pa_time_event *e;
348 pa_usec_t t;
350 pa_assert(a);
351 pa_assert(a->userdata);
352 pa_assert(callback);
354 t = timeval_load(tv);
356 m = a->userdata;
357 pa_assert(a == &m->api);
359 e = pa_xnew(pa_time_event, 1);
360 e->mainloop = m;
361 e->dead = FALSE;
363 if ((e->enabled = (t != PA_USEC_INVALID))) {
364 e->time = t;
366 m->n_enabled_time_events++;
368 if (m->cached_next_time_event) {
369 pa_assert(m->cached_next_time_event->enabled);
371 if (t < m->cached_next_time_event->time)
372 m->cached_next_time_event = e;
376 e->callback = callback;
377 e->userdata = userdata;
378 e->destroy_callback = NULL;
380 PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
382 if (e->enabled)
383 pa_mainloop_wakeup(m);
385 return e;
388 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
389 pa_bool_t valid;
390 pa_usec_t t;
392 pa_assert(e);
393 pa_assert(!e->dead);
395 t = timeval_load(tv);
397 valid = (t != PA_USEC_INVALID);
398 if (e->enabled && !valid) {
399 pa_assert(e->mainloop->n_enabled_time_events > 0);
400 e->mainloop->n_enabled_time_events--;
401 } else if (!e->enabled && valid)
402 e->mainloop->n_enabled_time_events++;
404 if ((e->enabled = valid)) {
405 e->time = t;
406 pa_mainloop_wakeup(e->mainloop);
409 if (e->mainloop->cached_next_time_event && e->enabled) {
410 pa_assert(e->mainloop->cached_next_time_event->enabled);
412 if (t < e->mainloop->cached_next_time_event->time)
413 e->mainloop->cached_next_time_event = e;
414 } else if (e->mainloop->cached_next_time_event == e)
415 e->mainloop->cached_next_time_event = NULL;
418 static void mainloop_time_free(pa_time_event *e) {
419 pa_assert(e);
420 pa_assert(!e->dead);
422 e->dead = TRUE;
423 e->mainloop->time_events_please_scan ++;
425 if (e->enabled) {
426 pa_assert(e->mainloop->n_enabled_time_events > 0);
427 e->mainloop->n_enabled_time_events--;
428 e->enabled = FALSE;
431 if (e->mainloop->cached_next_time_event == e)
432 e->mainloop->cached_next_time_event = NULL;
434 /* no wakeup needed here. Think about it! */
437 static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
438 pa_assert(e);
439 pa_assert(!e->dead);
441 e->destroy_callback = callback;
444 /* quit() */
446 static void mainloop_quit(pa_mainloop_api*a, int retval) {
447 pa_mainloop *m;
449 pa_assert(a);
450 pa_assert(a->userdata);
451 m = a->userdata;
452 pa_assert(a == &m->api);
454 pa_mainloop_quit(m, retval);
457 static const pa_mainloop_api vtable = {
458 .userdata = NULL,
460 .io_new = mainloop_io_new,
461 .io_enable = mainloop_io_enable,
462 .io_free = mainloop_io_free,
463 .io_set_destroy = mainloop_io_set_destroy,
465 .time_new = mainloop_time_new,
466 .time_restart = mainloop_time_restart,
467 .time_free = mainloop_time_free,
468 .time_set_destroy = mainloop_time_set_destroy,
470 .defer_new = mainloop_defer_new,
471 .defer_enable = mainloop_defer_enable,
472 .defer_free = mainloop_defer_free,
473 .defer_set_destroy = mainloop_defer_set_destroy,
475 .quit = mainloop_quit,
478 pa_mainloop *pa_mainloop_new(void) {
479 pa_mainloop *m;
481 pa_init_i18n();
483 m = pa_xnew(pa_mainloop, 1);
485 m->wakeup_pipe_type = 0;
486 if (pipe(m->wakeup_pipe) < 0) {
487 pa_log_error("ERROR: cannot create wakeup pipe");
488 pa_xfree(m);
489 return NULL;
492 pa_make_fd_nonblock(m->wakeup_pipe[0]);
493 pa_make_fd_nonblock(m->wakeup_pipe[1]);
494 pa_make_fd_cloexec(m->wakeup_pipe[0]);
495 pa_make_fd_cloexec(m->wakeup_pipe[1]);
496 m->wakeup_requested = FALSE;
498 PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
499 PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
500 PA_LLIST_HEAD_INIT(pa_defer_event, m->defer_events);
502 m->n_enabled_defer_events = m->n_enabled_time_events = m->n_io_events = 0;
503 m->io_events_please_scan = m->time_events_please_scan = m->defer_events_please_scan = 0;
505 m->cached_next_time_event = NULL;
506 m->prepared_timeout = 0;
508 m->pollfds = NULL;
509 m->max_pollfds = m->n_pollfds = 0;
510 m->rebuild_pollfds = TRUE;
512 m->quit = FALSE;
513 m->retval = 0;
515 m->api = vtable;
516 m->api.userdata = m;
518 m->state = STATE_PASSIVE;
520 m->poll_func = NULL;
521 m->poll_func_userdata = NULL;
522 m->poll_func_ret = -1;
524 return m;
527 static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
528 pa_io_event *e;
530 e = m->io_events;
531 while (e) {
532 pa_io_event *n = e->next;
534 if (!force && m->io_events_please_scan <= 0)
535 break;
537 if (force || e->dead) {
538 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
540 if (e->dead) {
541 pa_assert(m->io_events_please_scan > 0);
542 m->io_events_please_scan--;
545 if (e->destroy_callback)
546 e->destroy_callback(&m->api, e, e->userdata);
548 pa_xfree(e);
550 m->rebuild_pollfds = TRUE;
553 e = n;
556 pa_assert(m->io_events_please_scan == 0);
559 static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
560 pa_time_event *e;
562 e = m->time_events;
563 while (e) {
564 pa_time_event *n = e->next;
566 if (!force && m->time_events_please_scan <= 0)
567 break;
569 if (force || e->dead) {
570 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
572 if (e->dead) {
573 pa_assert(m->time_events_please_scan > 0);
574 m->time_events_please_scan--;
577 if (!e->dead && e->enabled) {
578 pa_assert(m->n_enabled_time_events > 0);
579 m->n_enabled_time_events--;
580 e->enabled = FALSE;
583 if (e->destroy_callback)
584 e->destroy_callback(&m->api, e, e->userdata);
586 pa_xfree(e);
589 e = n;
592 pa_assert(m->time_events_please_scan == 0);
595 static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
596 pa_defer_event *e;
598 e = m->defer_events;
599 while (e) {
600 pa_defer_event *n = e->next;
602 if (!force && m->defer_events_please_scan <= 0)
603 break;
605 if (force || e->dead) {
606 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
608 if (e->dead) {
609 pa_assert(m->defer_events_please_scan > 0);
610 m->defer_events_please_scan--;
613 if (!e->dead && e->enabled) {
614 pa_assert(m->n_enabled_defer_events > 0);
615 m->n_enabled_defer_events--;
616 e->enabled = FALSE;
619 if (e->destroy_callback)
620 e->destroy_callback(&m->api, e, e->userdata);
622 pa_xfree(e);
625 e = n;
628 pa_assert(m->defer_events_please_scan == 0);
632 void pa_mainloop_free(pa_mainloop* m) {
633 pa_assert(m);
635 cleanup_io_events(m, TRUE);
636 cleanup_defer_events(m, TRUE);
637 cleanup_time_events(m, TRUE);
639 pa_xfree(m->pollfds);
641 pa_close_pipe(m->wakeup_pipe);
643 pa_xfree(m);
646 static void scan_dead(pa_mainloop *m) {
647 pa_assert(m);
649 if (m->io_events_please_scan)
650 cleanup_io_events(m, FALSE);
652 if (m->time_events_please_scan)
653 cleanup_time_events(m, FALSE);
655 if (m->defer_events_please_scan)
656 cleanup_defer_events(m, FALSE);
659 static void rebuild_pollfds(pa_mainloop *m) {
660 pa_io_event*e;
661 struct pollfd *p;
662 unsigned l;
664 l = m->n_io_events + 1;
665 if (m->max_pollfds < l) {
666 l *= 2;
667 m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
668 m->max_pollfds = l;
671 m->n_pollfds = 0;
672 p = m->pollfds;
674 if (m->wakeup_pipe[0] >= 0) {
675 m->pollfds[0].fd = m->wakeup_pipe[0];
676 m->pollfds[0].events = POLLIN;
677 m->pollfds[0].revents = 0;
678 p++;
679 m->n_pollfds++;
682 for (e = m->io_events; e; e = e->next) {
683 if (e->dead) {
684 e->pollfd = NULL;
685 continue;
688 e->pollfd = p;
689 p->fd = e->fd;
690 p->events = map_flags_to_libc(e->events);
691 p->revents = 0;
693 p++;
694 m->n_pollfds++;
697 m->rebuild_pollfds = FALSE;
700 static int dispatch_pollfds(pa_mainloop *m) {
701 pa_io_event *e;
702 int r = 0, k;
704 pa_assert(m->poll_func_ret > 0);
706 for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) {
707 if (e->dead || !e->pollfd || !e->pollfd->revents)
708 continue;
710 pa_assert(e->pollfd->fd == e->fd);
711 pa_assert(e->callback);
712 e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
713 e->pollfd->revents = 0;
714 r++;
716 k--;
719 return r;
722 static int dispatch_defer(pa_mainloop *m) {
723 pa_defer_event *e;
724 int r = 0;
726 if (m->n_enabled_defer_events <= 0)
727 return 0;
729 for (e = m->defer_events; e && !m->quit; e = e->next) {
730 if (e->dead || !e->enabled)
731 continue;
733 pa_assert(e->callback);
734 e->callback(&m->api, e, e->userdata);
735 r++;
738 return r;
741 static pa_time_event* find_next_time_event(pa_mainloop *m) {
742 pa_time_event *t, *n = NULL;
743 pa_assert(m);
745 if (m->cached_next_time_event)
746 return m->cached_next_time_event;
748 for (t = m->time_events; t; t = t->next) {
750 if (t->dead || !t->enabled)
751 continue;
753 if (!n || t->time < n->time) {
754 n = t;
756 /* Shortcut for time == 0 */
757 if (n->time == 0)
758 break;
762 m->cached_next_time_event = n;
763 return n;
766 static int calc_next_timeout(pa_mainloop *m) {
767 pa_time_event *t;
768 pa_usec_t usec;
770 if (!m->n_enabled_time_events)
771 return -1;
773 t = find_next_time_event(m);
774 pa_assert(t);
776 if (t->time == 0)
777 return 0;
779 usec = t->time - pa_rtclock_now();
781 if (usec <= 0)
782 return 0;
784 return (int) (usec / 1000); /* in milliseconds */
787 static int dispatch_timeout(pa_mainloop *m) {
788 pa_time_event *e;
789 pa_usec_t now;
790 int r = 0;
791 pa_assert(m);
793 if (m->n_enabled_time_events <= 0)
794 return 0;
796 now = pa_rtclock_now();
798 for (e = m->time_events; e && !m->quit; e = e->next) {
800 if (e->dead || !e->enabled)
801 continue;
803 if (e->time <= now) {
804 struct timeval tv;
805 pa_assert(e->callback);
807 /* Disable time event */
808 mainloop_time_restart(e, NULL);
810 e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata);
812 r++;
816 return r;
819 void pa_mainloop_wakeup(pa_mainloop *m) {
820 char c = 'W';
821 pa_assert(m);
823 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
824 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
825 m->wakeup_requested++;
829 static void clear_wakeup(pa_mainloop *m) {
830 char c[10];
832 pa_assert(m);
834 if (m->wakeup_pipe[0] < 0)
835 return;
837 if (m->wakeup_requested) {
838 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c));
839 m->wakeup_requested = 0;
843 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
844 pa_assert(m);
845 pa_assert(m->state == STATE_PASSIVE);
847 clear_wakeup(m);
848 scan_dead(m);
850 if (m->quit)
851 goto quit;
853 if (m->n_enabled_defer_events <= 0) {
854 if (m->rebuild_pollfds)
855 rebuild_pollfds(m);
857 m->prepared_timeout = calc_next_timeout(m);
858 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
859 m->prepared_timeout = timeout;
862 m->state = STATE_PREPARED;
863 return 0;
865 quit:
866 m->state = STATE_QUIT;
867 return -2;
870 int pa_mainloop_poll(pa_mainloop *m) {
871 pa_assert(m);
872 pa_assert(m->state == STATE_PREPARED);
874 if (m->quit)
875 goto quit;
877 m->state = STATE_POLLING;
879 if (m->n_enabled_defer_events )
880 m->poll_func_ret = 0;
881 else {
882 pa_assert(!m->rebuild_pollfds);
884 if (m->poll_func)
885 m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
886 else
887 m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
889 if (m->poll_func_ret < 0) {
890 if (errno == EINTR)
891 m->poll_func_ret = 0;
892 else
893 pa_log("poll(): %s", pa_cstrerror(errno));
897 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
898 return m->poll_func_ret;
900 quit:
901 m->state = STATE_QUIT;
902 return -2;
905 int pa_mainloop_dispatch(pa_mainloop *m) {
906 int dispatched = 0;
908 pa_assert(m);
909 pa_assert(m->state == STATE_POLLED);
911 if (m->quit)
912 goto quit;
914 if (m->n_enabled_defer_events)
915 dispatched += dispatch_defer(m);
916 else {
917 if (m->n_enabled_time_events)
918 dispatched += dispatch_timeout(m);
920 if (m->quit)
921 goto quit;
923 if (m->poll_func_ret > 0)
924 dispatched += dispatch_pollfds(m);
927 if (m->quit)
928 goto quit;
930 m->state = STATE_PASSIVE;
932 return dispatched;
934 quit:
935 m->state = STATE_QUIT;
936 return -2;
939 int pa_mainloop_get_retval(pa_mainloop *m) {
940 pa_assert(m);
941 return m->retval;
944 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
945 int r;
946 pa_assert(m);
948 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
949 goto quit;
951 if ((r = pa_mainloop_poll(m)) < 0)
952 goto quit;
954 if ((r = pa_mainloop_dispatch(m)) < 0)
955 goto quit;
957 return r;
959 quit:
961 if ((r == -2) && retval)
962 *retval = pa_mainloop_get_retval(m);
963 return r;
966 int pa_mainloop_run(pa_mainloop *m, int *retval) {
967 int r;
969 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
971 if (r == -2)
972 return 1;
973 else if (r < 0)
974 return -1;
975 else
976 return 0;
979 void pa_mainloop_quit(pa_mainloop *m, int retval) {
980 pa_assert(m);
982 m->quit = TRUE;
983 m->retval = retval;
984 pa_mainloop_wakeup(m);
987 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
988 pa_assert(m);
989 return &m->api;
992 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
993 pa_assert(m);
995 m->poll_func = poll_func;
996 m->poll_func_userdata = userdata;
999 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
1000 pa_assert(m);
1002 return m->io_new == mainloop_io_new;