Merge commit 'jprvita2/master'
[pulseaudio-mirror.git] / src / pulse / mainloop.c
blob93a4742d0263de8ae12fab62834bbe2bebee489a
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 clock_now;
770 if (!m->n_enabled_time_events)
771 return -1;
773 pa_assert_se(t = find_next_time_event(m));
775 if (t->time <= 0)
776 return 0;
778 clock_now = pa_rtclock_now();
780 if (t->time <= clock_now)
781 return 0;
783 return (int) ((t->time - clock_now) / 1000); /* in milliseconds */
786 static int dispatch_timeout(pa_mainloop *m) {
787 pa_time_event *e;
788 pa_usec_t now;
789 int r = 0;
790 pa_assert(m);
792 if (m->n_enabled_time_events <= 0)
793 return 0;
795 now = pa_rtclock_now();
797 for (e = m->time_events; e && !m->quit; e = e->next) {
799 if (e->dead || !e->enabled)
800 continue;
802 if (e->time <= now) {
803 struct timeval tv;
804 pa_assert(e->callback);
806 /* Disable time event */
807 mainloop_time_restart(e, NULL);
809 e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata);
811 r++;
815 return r;
818 void pa_mainloop_wakeup(pa_mainloop *m) {
819 char c = 'W';
820 pa_assert(m);
822 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
823 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
824 m->wakeup_requested++;
828 static void clear_wakeup(pa_mainloop *m) {
829 char c[10];
831 pa_assert(m);
833 if (m->wakeup_pipe[0] < 0)
834 return;
836 if (m->wakeup_requested) {
837 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c));
838 m->wakeup_requested = 0;
842 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
843 pa_assert(m);
844 pa_assert(m->state == STATE_PASSIVE);
846 clear_wakeup(m);
847 scan_dead(m);
849 if (m->quit)
850 goto quit;
852 if (m->n_enabled_defer_events <= 0) {
853 if (m->rebuild_pollfds)
854 rebuild_pollfds(m);
856 m->prepared_timeout = calc_next_timeout(m);
857 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
858 m->prepared_timeout = timeout;
861 m->state = STATE_PREPARED;
862 return 0;
864 quit:
865 m->state = STATE_QUIT;
866 return -2;
869 int pa_mainloop_poll(pa_mainloop *m) {
870 pa_assert(m);
871 pa_assert(m->state == STATE_PREPARED);
873 if (m->quit)
874 goto quit;
876 m->state = STATE_POLLING;
878 if (m->n_enabled_defer_events )
879 m->poll_func_ret = 0;
880 else {
881 pa_assert(!m->rebuild_pollfds);
883 if (m->poll_func)
884 m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
885 else
886 m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
888 if (m->poll_func_ret < 0) {
889 if (errno == EINTR)
890 m->poll_func_ret = 0;
891 else
892 pa_log("poll(): %s", pa_cstrerror(errno));
896 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
897 return m->poll_func_ret;
899 quit:
900 m->state = STATE_QUIT;
901 return -2;
904 int pa_mainloop_dispatch(pa_mainloop *m) {
905 int dispatched = 0;
907 pa_assert(m);
908 pa_assert(m->state == STATE_POLLED);
910 if (m->quit)
911 goto quit;
913 if (m->n_enabled_defer_events)
914 dispatched += dispatch_defer(m);
915 else {
916 if (m->n_enabled_time_events)
917 dispatched += dispatch_timeout(m);
919 if (m->quit)
920 goto quit;
922 if (m->poll_func_ret > 0)
923 dispatched += dispatch_pollfds(m);
926 if (m->quit)
927 goto quit;
929 m->state = STATE_PASSIVE;
931 return dispatched;
933 quit:
934 m->state = STATE_QUIT;
935 return -2;
938 int pa_mainloop_get_retval(pa_mainloop *m) {
939 pa_assert(m);
940 return m->retval;
943 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
944 int r;
945 pa_assert(m);
947 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
948 goto quit;
950 if ((r = pa_mainloop_poll(m)) < 0)
951 goto quit;
953 if ((r = pa_mainloop_dispatch(m)) < 0)
954 goto quit;
956 return r;
958 quit:
960 if ((r == -2) && retval)
961 *retval = pa_mainloop_get_retval(m);
962 return r;
965 int pa_mainloop_run(pa_mainloop *m, int *retval) {
966 int r;
968 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
970 if (r == -2)
971 return 1;
972 else if (r < 0)
973 return -1;
974 else
975 return 0;
978 void pa_mainloop_quit(pa_mainloop *m, int retval) {
979 pa_assert(m);
981 m->quit = TRUE;
982 m->retval = retval;
983 pa_mainloop_wakeup(m);
986 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
987 pa_assert(m);
988 return &m->api;
991 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
992 pa_assert(m);
994 m->poll_func = poll_func;
995 m->poll_func_userdata = userdata;
998 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
999 pa_assert(m);
1001 return m->io_new == mainloop_io_new;