mainloop, glib-mainloop: time_restart could cause incorrect event ordering
[platform/upstream/pulseaudio.git] / src / pulse / mainloop.c
1 /***
2   This file is part of PulseAudio.
3
4   Copyright 2004-2006 Lennart Poettering
5   Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
6
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.
11
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.
16
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 ***/
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <fcntl.h>
31 #include <errno.h>
32
33 #ifndef HAVE_PIPE
34 #include <pulsecore/pipe.h>
35 #endif
36
37 #include <pulse/rtclock.h>
38 #include <pulse/timeval.h>
39 #include <pulse/xmalloc.h>
40
41 #include <pulsecore/poll.h>
42 #include <pulsecore/core-rtclock.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/i18n.h>
45 #include <pulsecore/llist.h>
46 #include <pulsecore/log.h>
47 #include <pulsecore/core-error.h>
48 #include <pulsecore/socket.h>
49 #include <pulsecore/macro.h>
50
51 #include "mainloop.h"
52 #include "internal.h"
53
54 struct pa_io_event {
55     pa_mainloop *mainloop;
56     bool dead:1;
57
58     int fd;
59     pa_io_event_flags_t events;
60     struct pollfd *pollfd;
61
62     pa_io_event_cb_t callback;
63     void *userdata;
64     pa_io_event_destroy_cb_t destroy_callback;
65
66     PA_LLIST_FIELDS(pa_io_event);
67 };
68
69 struct pa_time_event {
70     pa_mainloop *mainloop;
71     bool dead:1;
72
73     bool enabled:1;
74     bool use_rtclock:1;
75     pa_usec_t time;
76
77     pa_time_event_cb_t callback;
78     void *userdata;
79     pa_time_event_destroy_cb_t destroy_callback;
80
81     PA_LLIST_FIELDS(pa_time_event);
82 };
83
84 struct pa_defer_event {
85     pa_mainloop *mainloop;
86     bool dead:1;
87
88     bool enabled:1;
89
90     pa_defer_event_cb_t callback;
91     void *userdata;
92     pa_defer_event_destroy_cb_t destroy_callback;
93
94     PA_LLIST_FIELDS(pa_defer_event);
95 };
96
97 struct pa_mainloop {
98     PA_LLIST_HEAD(pa_io_event, io_events);
99     PA_LLIST_HEAD(pa_time_event, time_events);
100     PA_LLIST_HEAD(pa_defer_event, defer_events);
101
102     unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
103     unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
104
105     bool rebuild_pollfds:1;
106     struct pollfd *pollfds;
107     unsigned max_pollfds, n_pollfds;
108
109     pa_usec_t prepared_timeout;
110     pa_time_event *cached_next_time_event;
111
112     pa_mainloop_api api;
113
114     int retval;
115     bool quit:1;
116
117     pa_atomic_t wakeup_requested;
118     int wakeup_pipe[2];
119     int wakeup_pipe_type;
120
121     enum {
122         STATE_PASSIVE,
123         STATE_PREPARED,
124         STATE_POLLING,
125         STATE_POLLED,
126         STATE_QUIT
127     } state;
128
129     pa_poll_func poll_func;
130     void *poll_func_userdata;
131     int poll_func_ret;
132 };
133
134 static short map_flags_to_libc(pa_io_event_flags_t flags) {
135     return (short)
136         ((flags & PA_IO_EVENT_INPUT ? POLLIN : 0) |
137          (flags & PA_IO_EVENT_OUTPUT ? POLLOUT : 0) |
138          (flags & PA_IO_EVENT_ERROR ? POLLERR : 0) |
139          (flags & PA_IO_EVENT_HANGUP ? POLLHUP : 0));
140 }
141
142 static pa_io_event_flags_t map_flags_from_libc(short flags) {
143     return
144         (flags & POLLIN ? PA_IO_EVENT_INPUT : 0) |
145         (flags & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
146         (flags & POLLERR ? PA_IO_EVENT_ERROR : 0) |
147         (flags & POLLHUP ? PA_IO_EVENT_HANGUP : 0);
148 }
149
150 /* IO events */
151 static pa_io_event* mainloop_io_new(
152         pa_mainloop_api *a,
153         int fd,
154         pa_io_event_flags_t events,
155         pa_io_event_cb_t callback,
156         void *userdata) {
157
158     pa_mainloop *m;
159     pa_io_event *e;
160
161     pa_assert(a);
162     pa_assert(a->userdata);
163     pa_assert(fd >= 0);
164     pa_assert(callback);
165
166     m = a->userdata;
167     pa_assert(a == &m->api);
168
169     e = pa_xnew0(pa_io_event, 1);
170     e->mainloop = m;
171
172     e->fd = fd;
173     e->events = events;
174
175     e->callback = callback;
176     e->userdata = userdata;
177
178     PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
179     m->rebuild_pollfds = true;
180     m->n_io_events ++;
181
182     pa_mainloop_wakeup(m);
183
184     return e;
185 }
186
187 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
188     pa_assert(e);
189     pa_assert(!e->dead);
190
191     if (e->events == events)
192         return;
193
194     e->events = events;
195
196     if (e->pollfd)
197         e->pollfd->events = map_flags_to_libc(events);
198     else
199         e->mainloop->rebuild_pollfds = true;
200
201     pa_mainloop_wakeup(e->mainloop);
202 }
203
204 static void mainloop_io_free(pa_io_event *e) {
205     pa_assert(e);
206     pa_assert(!e->dead);
207
208     e->dead = true;
209     e->mainloop->io_events_please_scan ++;
210
211     e->mainloop->n_io_events --;
212     e->mainloop->rebuild_pollfds = true;
213
214     pa_mainloop_wakeup(e->mainloop);
215 }
216
217 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
218     pa_assert(e);
219
220     e->destroy_callback = callback;
221 }
222
223 /* Defer events */
224 static pa_defer_event* mainloop_defer_new(
225         pa_mainloop_api *a,
226         pa_defer_event_cb_t callback,
227         void *userdata) {
228
229     pa_mainloop *m;
230     pa_defer_event *e;
231
232     pa_assert(a);
233     pa_assert(a->userdata);
234     pa_assert(callback);
235
236     m = a->userdata;
237     pa_assert(a == &m->api);
238
239     e = pa_xnew0(pa_defer_event, 1);
240     e->mainloop = m;
241
242     e->enabled = true;
243     m->n_enabled_defer_events++;
244
245     e->callback = callback;
246     e->userdata = userdata;
247
248     PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
249
250     pa_mainloop_wakeup(e->mainloop);
251
252     return e;
253 }
254
255 static void mainloop_defer_enable(pa_defer_event *e, int b) {
256     pa_assert(e);
257     pa_assert(!e->dead);
258
259     if (e->enabled && !b) {
260         pa_assert(e->mainloop->n_enabled_defer_events > 0);
261         e->mainloop->n_enabled_defer_events--;
262     } else if (!e->enabled && b) {
263         e->mainloop->n_enabled_defer_events++;
264         pa_mainloop_wakeup(e->mainloop);
265     }
266
267     e->enabled = b;
268 }
269
270 static void mainloop_defer_free(pa_defer_event *e) {
271     pa_assert(e);
272     pa_assert(!e->dead);
273
274     e->dead = true;
275     e->mainloop->defer_events_please_scan ++;
276
277     if (e->enabled) {
278         pa_assert(e->mainloop->n_enabled_defer_events > 0);
279         e->mainloop->n_enabled_defer_events--;
280         e->enabled = false;
281     }
282 }
283
284 static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
285     pa_assert(e);
286     pa_assert(!e->dead);
287
288     e->destroy_callback = callback;
289 }
290
291 /* Time events */
292 static pa_usec_t make_rt(const struct timeval *tv, bool *use_rtclock) {
293     struct timeval ttv;
294
295     if (!tv) {
296         *use_rtclock = false;
297         return PA_USEC_INVALID;
298     }
299
300     ttv = *tv;
301     *use_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
302
303     if (*use_rtclock)
304         ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
305     else
306         pa_rtclock_from_wallclock(&ttv);
307
308     return pa_timeval_load(&ttv);
309 }
310
311 static pa_time_event* mainloop_time_new(
312         pa_mainloop_api *a,
313         const struct timeval *tv,
314         pa_time_event_cb_t callback,
315         void *userdata) {
316
317     pa_mainloop *m;
318     pa_time_event *e;
319     pa_usec_t t;
320     bool use_rtclock = false;
321
322     pa_assert(a);
323     pa_assert(a->userdata);
324     pa_assert(callback);
325
326     t = make_rt(tv, &use_rtclock);
327
328     m = a->userdata;
329     pa_assert(a == &m->api);
330
331     e = pa_xnew0(pa_time_event, 1);
332     e->mainloop = m;
333
334     if ((e->enabled = (t != PA_USEC_INVALID))) {
335         e->time = t;
336         e->use_rtclock = use_rtclock;
337
338         m->n_enabled_time_events++;
339
340         if (m->cached_next_time_event) {
341             pa_assert(m->cached_next_time_event->enabled);
342
343             if (t < m->cached_next_time_event->time)
344                 m->cached_next_time_event = e;
345         }
346     }
347
348     e->callback = callback;
349     e->userdata = userdata;
350
351     PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
352
353     if (e->enabled)
354         pa_mainloop_wakeup(m);
355
356     return e;
357 }
358
359 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
360     bool valid;
361     pa_usec_t t;
362     bool use_rtclock = false;
363
364     pa_assert(e);
365     pa_assert(!e->dead);
366
367     t = make_rt(tv, &use_rtclock);
368
369     valid = (t != PA_USEC_INVALID);
370     if (e->enabled && !valid) {
371         pa_assert(e->mainloop->n_enabled_time_events > 0);
372         e->mainloop->n_enabled_time_events--;
373     } else if (!e->enabled && valid)
374         e->mainloop->n_enabled_time_events++;
375
376     if ((e->enabled = valid)) {
377         e->time = t;
378         e->use_rtclock = use_rtclock;
379         pa_mainloop_wakeup(e->mainloop);
380     }
381
382     if (e->mainloop->cached_next_time_event == e)
383         e->mainloop->cached_next_time_event = NULL;
384
385     if (e->mainloop->cached_next_time_event && e->enabled) {
386         pa_assert(e->mainloop->cached_next_time_event->enabled);
387
388         if (t < e->mainloop->cached_next_time_event->time)
389             e->mainloop->cached_next_time_event = e;
390     }
391 }
392
393 static void mainloop_time_free(pa_time_event *e) {
394     pa_assert(e);
395     pa_assert(!e->dead);
396
397     e->dead = true;
398     e->mainloop->time_events_please_scan ++;
399
400     if (e->enabled) {
401         pa_assert(e->mainloop->n_enabled_time_events > 0);
402         e->mainloop->n_enabled_time_events--;
403         e->enabled = false;
404     }
405
406     if (e->mainloop->cached_next_time_event == e)
407         e->mainloop->cached_next_time_event = NULL;
408
409     /* no wakeup needed here. Think about it! */
410 }
411
412 static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
413     pa_assert(e);
414     pa_assert(!e->dead);
415
416     e->destroy_callback = callback;
417 }
418
419 /* quit() */
420
421 static void mainloop_quit(pa_mainloop_api *a, int retval) {
422     pa_mainloop *m;
423
424     pa_assert(a);
425     pa_assert(a->userdata);
426     m = a->userdata;
427     pa_assert(a == &m->api);
428
429     pa_mainloop_quit(m, retval);
430 }
431
432 static const pa_mainloop_api vtable = {
433     .userdata = NULL,
434
435     .io_new = mainloop_io_new,
436     .io_enable = mainloop_io_enable,
437     .io_free = mainloop_io_free,
438     .io_set_destroy = mainloop_io_set_destroy,
439
440     .time_new = mainloop_time_new,
441     .time_restart = mainloop_time_restart,
442     .time_free = mainloop_time_free,
443     .time_set_destroy = mainloop_time_set_destroy,
444
445     .defer_new = mainloop_defer_new,
446     .defer_enable = mainloop_defer_enable,
447     .defer_free = mainloop_defer_free,
448     .defer_set_destroy = mainloop_defer_set_destroy,
449
450     .quit = mainloop_quit,
451 };
452
453 pa_mainloop *pa_mainloop_new(void) {
454     pa_mainloop *m;
455
456     pa_init_i18n();
457
458     m = pa_xnew0(pa_mainloop, 1);
459
460     if (pa_pipe_cloexec(m->wakeup_pipe) < 0) {
461         pa_log_error("ERROR: cannot create wakeup pipe");
462         pa_xfree(m);
463         return NULL;
464     }
465
466     pa_make_fd_nonblock(m->wakeup_pipe[0]);
467     pa_make_fd_nonblock(m->wakeup_pipe[1]);
468
469     m->rebuild_pollfds = true;
470
471     m->api = vtable;
472     m->api.userdata = m;
473
474     m->state = STATE_PASSIVE;
475
476     m->poll_func_ret = -1;
477
478     return m;
479 }
480
481 static void cleanup_io_events(pa_mainloop *m, bool force) {
482     pa_io_event *e, *n;
483
484     PA_LLIST_FOREACH_SAFE(e, n, m->io_events) {
485
486         if (!force && m->io_events_please_scan <= 0)
487             break;
488
489         if (force || e->dead) {
490             PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
491
492             if (e->dead) {
493                 pa_assert(m->io_events_please_scan > 0);
494                 m->io_events_please_scan--;
495             }
496
497             if (e->destroy_callback)
498                 e->destroy_callback(&m->api, e, e->userdata);
499
500             pa_xfree(e);
501
502             m->rebuild_pollfds = true;
503         }
504     }
505
506     pa_assert(m->io_events_please_scan == 0);
507 }
508
509 static void cleanup_time_events(pa_mainloop *m, bool force) {
510     pa_time_event *e, *n;
511
512     PA_LLIST_FOREACH_SAFE(e, n, m->time_events) {
513
514         if (!force && m->time_events_please_scan <= 0)
515             break;
516
517         if (force || e->dead) {
518             PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
519
520             if (e->dead) {
521                 pa_assert(m->time_events_please_scan > 0);
522                 m->time_events_please_scan--;
523             }
524
525             if (!e->dead && e->enabled) {
526                 pa_assert(m->n_enabled_time_events > 0);
527                 m->n_enabled_time_events--;
528                 e->enabled = false;
529             }
530
531             if (e->destroy_callback)
532                 e->destroy_callback(&m->api, e, e->userdata);
533
534             pa_xfree(e);
535         }
536     }
537
538     pa_assert(m->time_events_please_scan == 0);
539 }
540
541 static void cleanup_defer_events(pa_mainloop *m, bool force) {
542     pa_defer_event *e, *n;
543
544     PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) {
545
546         if (!force && m->defer_events_please_scan <= 0)
547             break;
548
549         if (force || e->dead) {
550             PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
551
552             if (e->dead) {
553                 pa_assert(m->defer_events_please_scan > 0);
554                 m->defer_events_please_scan--;
555             }
556
557             if (!e->dead && e->enabled) {
558                 pa_assert(m->n_enabled_defer_events > 0);
559                 m->n_enabled_defer_events--;
560                 e->enabled = false;
561             }
562
563             if (e->destroy_callback)
564                 e->destroy_callback(&m->api, e, e->userdata);
565
566             pa_xfree(e);
567         }
568     }
569
570     pa_assert(m->defer_events_please_scan == 0);
571 }
572
573 void pa_mainloop_free(pa_mainloop *m) {
574     pa_assert(m);
575
576     cleanup_io_events(m, true);
577     cleanup_defer_events(m, true);
578     cleanup_time_events(m, true);
579
580     pa_xfree(m->pollfds);
581
582     pa_close_pipe(m->wakeup_pipe);
583
584     pa_xfree(m);
585 }
586
587 static void scan_dead(pa_mainloop *m) {
588     pa_assert(m);
589
590     if (m->io_events_please_scan)
591         cleanup_io_events(m, false);
592
593     if (m->time_events_please_scan)
594         cleanup_time_events(m, false);
595
596     if (m->defer_events_please_scan)
597         cleanup_defer_events(m, false);
598 }
599
600 static void rebuild_pollfds(pa_mainloop *m) {
601     pa_io_event*e;
602     struct pollfd *p;
603     unsigned l;
604
605     l = m->n_io_events + 1;
606     if (m->max_pollfds < l) {
607         l *= 2;
608         m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
609         m->max_pollfds = l;
610     }
611
612     m->n_pollfds = 0;
613     p = m->pollfds;
614
615     m->pollfds[0].fd = m->wakeup_pipe[0];
616     m->pollfds[0].events = POLLIN;
617     m->pollfds[0].revents = 0;
618     p++;
619     m->n_pollfds++;
620
621     PA_LLIST_FOREACH(e, m->io_events) {
622         if (e->dead) {
623             e->pollfd = NULL;
624             continue;
625         }
626
627         e->pollfd = p;
628         p->fd = e->fd;
629         p->events = map_flags_to_libc(e->events);
630         p->revents = 0;
631
632         p++;
633         m->n_pollfds++;
634     }
635
636     m->rebuild_pollfds = false;
637 }
638
639 static unsigned dispatch_pollfds(pa_mainloop *m) {
640     pa_io_event *e;
641     unsigned r = 0, k;
642
643     pa_assert(m->poll_func_ret > 0);
644
645     k = m->poll_func_ret;
646
647     PA_LLIST_FOREACH(e, m->io_events) {
648
649         if (k <= 0 || m->quit)
650             break;
651
652         if (e->dead || !e->pollfd || !e->pollfd->revents)
653             continue;
654
655         pa_assert(e->pollfd->fd == e->fd);
656         pa_assert(e->callback);
657
658         e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
659         e->pollfd->revents = 0;
660         r++;
661         k--;
662     }
663
664     return r;
665 }
666
667 static unsigned dispatch_defer(pa_mainloop *m) {
668     pa_defer_event *e;
669     unsigned r = 0;
670
671     if (m->n_enabled_defer_events <= 0)
672         return 0;
673
674     PA_LLIST_FOREACH(e, m->defer_events) {
675
676         if (m->quit)
677             break;
678
679         if (e->dead || !e->enabled)
680             continue;
681
682         pa_assert(e->callback);
683         e->callback(&m->api, e, e->userdata);
684         r++;
685     }
686
687     return r;
688 }
689
690 static pa_time_event* find_next_time_event(pa_mainloop *m) {
691     pa_time_event *t, *n = NULL;
692     pa_assert(m);
693
694     if (m->cached_next_time_event)
695         return m->cached_next_time_event;
696
697     PA_LLIST_FOREACH(t, m->time_events) {
698
699         if (t->dead || !t->enabled)
700             continue;
701
702         if (!n || t->time < n->time) {
703             n = t;
704
705             /* Shortcut for time == 0 */
706             if (n->time == 0)
707                 break;
708         }
709     }
710
711     m->cached_next_time_event = n;
712     return n;
713 }
714
715 static pa_usec_t calc_next_timeout(pa_mainloop *m) {
716     pa_time_event *t;
717     pa_usec_t clock_now;
718
719     if (m->n_enabled_time_events <= 0)
720         return PA_USEC_INVALID;
721
722     pa_assert_se(t = find_next_time_event(m));
723
724     if (t->time <= 0)
725         return 0;
726
727     clock_now = pa_rtclock_now();
728
729     if (t->time <= clock_now)
730         return 0;
731
732     return t->time - clock_now;
733 }
734
735 static unsigned dispatch_timeout(pa_mainloop *m) {
736     pa_time_event *e;
737     pa_usec_t now;
738     unsigned r = 0;
739     pa_assert(m);
740
741     if (m->n_enabled_time_events <= 0)
742         return 0;
743
744     now = pa_rtclock_now();
745
746     PA_LLIST_FOREACH(e, m->time_events) {
747
748         if (m->quit)
749             break;
750
751         if (e->dead || !e->enabled)
752             continue;
753
754         if (e->time <= now) {
755             struct timeval tv;
756             pa_assert(e->callback);
757
758             /* Disable time event */
759             mainloop_time_restart(e, NULL);
760
761             e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata);
762
763             r++;
764         }
765     }
766
767     return r;
768 }
769
770 void pa_mainloop_wakeup(pa_mainloop *m) {
771     char c = 'W';
772     pa_assert(m);
773
774     if (pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type) < 0)
775         /* Not much options for recovering from the error. Let's at least log something. */
776         pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno));
777
778     pa_atomic_store(&m->wakeup_requested, true);
779 }
780
781 static void clear_wakeup(pa_mainloop *m) {
782     char c[10];
783
784     pa_assert(m);
785
786     if (pa_atomic_cmpxchg(&m->wakeup_requested, true, false)) {
787         while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c))
788             ;
789     }
790 }
791
792 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
793     pa_assert(m);
794     pa_assert(m->state == STATE_PASSIVE);
795
796     clear_wakeup(m);
797     scan_dead(m);
798
799     if (m->quit)
800         goto quit;
801
802     if (m->n_enabled_defer_events <= 0) {
803
804         if (m->rebuild_pollfds)
805             rebuild_pollfds(m);
806
807         m->prepared_timeout = calc_next_timeout(m);
808         if (timeout >= 0) {
809             uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC;
810
811             if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID)
812                 m->prepared_timeout = timeout;
813         }
814     }
815
816     m->state = STATE_PREPARED;
817     return 0;
818
819 quit:
820     m->state = STATE_QUIT;
821     return -2;
822 }
823
824 static int usec_to_timeout(pa_usec_t u) {
825     int timeout;
826
827     if (u == PA_USEC_INVALID)
828         return -1;
829
830     timeout = (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
831     pa_assert(timeout >= 0);
832
833     return timeout;
834 }
835
836 int pa_mainloop_poll(pa_mainloop *m) {
837     pa_assert(m);
838     pa_assert(m->state == STATE_PREPARED);
839
840     if (m->quit)
841         goto quit;
842
843     m->state = STATE_POLLING;
844
845     if (m->n_enabled_defer_events )
846         m->poll_func_ret = 0;
847     else {
848         pa_assert(!m->rebuild_pollfds);
849
850         if (m->poll_func)
851             m->poll_func_ret = m->poll_func(
852                     m->pollfds, m->n_pollfds,
853                     usec_to_timeout(m->prepared_timeout),
854                     m->poll_func_userdata);
855         else {
856 #ifdef HAVE_PPOLL
857             struct timespec ts;
858
859             m->poll_func_ret = ppoll(
860                     m->pollfds, m->n_pollfds,
861                     m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout),
862                     NULL);
863 #else
864             m->poll_func_ret = pa_poll(
865                     m->pollfds, m->n_pollfds,
866                     usec_to_timeout(m->prepared_timeout));
867 #endif
868         }
869
870         if (m->poll_func_ret < 0) {
871             if (errno == EINTR)
872                 m->poll_func_ret = 0;
873             else
874                 pa_log("poll(): %s", pa_cstrerror(errno));
875         }
876     }
877
878     m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
879     return m->poll_func_ret;
880
881 quit:
882     m->state = STATE_QUIT;
883     return -2;
884 }
885
886 int pa_mainloop_dispatch(pa_mainloop *m) {
887     unsigned dispatched = 0;
888
889     pa_assert(m);
890     pa_assert(m->state == STATE_POLLED);
891
892     if (m->quit)
893         goto quit;
894
895     if (m->n_enabled_defer_events)
896         dispatched += dispatch_defer(m);
897     else {
898         if (m->n_enabled_time_events)
899             dispatched += dispatch_timeout(m);
900
901         if (m->quit)
902             goto quit;
903
904         if (m->poll_func_ret > 0)
905             dispatched += dispatch_pollfds(m);
906     }
907
908     if (m->quit)
909         goto quit;
910
911     m->state = STATE_PASSIVE;
912
913     return (int) dispatched;
914
915 quit:
916     m->state = STATE_QUIT;
917     return -2;
918 }
919
920 int pa_mainloop_get_retval(pa_mainloop *m) {
921     pa_assert(m);
922
923     return m->retval;
924 }
925
926 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
927     int r;
928     pa_assert(m);
929
930     if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
931         goto quit;
932
933     if ((r = pa_mainloop_poll(m)) < 0)
934         goto quit;
935
936     if ((r = pa_mainloop_dispatch(m)) < 0)
937         goto quit;
938
939     return r;
940
941 quit:
942
943     if ((r == -2) && retval)
944         *retval = pa_mainloop_get_retval(m);
945     return r;
946 }
947
948 int pa_mainloop_run(pa_mainloop *m, int *retval) {
949     int r;
950
951     while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0)
952         ;
953
954     if (r == -2)
955         return 1;
956     else if (r < 0)
957         return -1;
958     else
959         return 0;
960 }
961
962 void pa_mainloop_quit(pa_mainloop *m, int retval) {
963     pa_assert(m);
964
965     m->quit = true;
966     m->retval = retval;
967     pa_mainloop_wakeup(m);
968 }
969
970 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop *m) {
971     pa_assert(m);
972
973     return &m->api;
974 }
975
976 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
977     pa_assert(m);
978
979     m->poll_func = poll_func;
980     m->poll_func_userdata = userdata;
981 }
982
983 bool pa_mainloop_is_our_api(pa_mainloop_api *m) {
984     pa_assert(m);
985
986     return m->io_new == mainloop_io_new;
987 }