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