]> code.delx.au - pulseaudio/blob - src/pulse/mainloop.c
f02d31a149474eacfe1a072e446393866fe4d528
[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 #ifndef HAVE_PIPE
36 #include <pulsecore/pipe.h>
37 #endif
38
39 #include <pulse/i18n.h>
40 #include <pulse/rtclock.h>
41 #include <pulse/timeval.h>
42 #include <pulse/xmalloc.h>
43
44 #include <pulsecore/poll.h>
45 #include <pulsecore/core-rtclock.h>
46 #include <pulsecore/core-util.h>
47 #include <pulsecore/llist.h>
48 #include <pulsecore/log.h>
49 #include <pulsecore/core-error.h>
50 #include <pulsecore/socket.h>
51 #include <pulsecore/macro.h>
52
53 #include "mainloop.h"
54 #include "internal.h"
55
56 struct pa_io_event {
57 pa_mainloop *mainloop;
58 pa_bool_t dead:1;
59
60 int fd;
61 pa_io_event_flags_t events;
62 struct pollfd *pollfd;
63
64 pa_io_event_cb_t callback;
65 void *userdata;
66 pa_io_event_destroy_cb_t destroy_callback;
67
68 PA_LLIST_FIELDS(pa_io_event);
69 };
70
71 struct pa_time_event {
72 pa_mainloop *mainloop;
73 pa_bool_t dead:1;
74
75 pa_bool_t enabled:1;
76 pa_bool_t use_rtclock:1;
77 pa_usec_t time;
78
79 pa_time_event_cb_t callback;
80 void *userdata;
81 pa_time_event_destroy_cb_t destroy_callback;
82
83 PA_LLIST_FIELDS(pa_time_event);
84 };
85
86 struct pa_defer_event {
87 pa_mainloop *mainloop;
88 pa_bool_t dead:1;
89
90 pa_bool_t enabled:1;
91
92 pa_defer_event_cb_t callback;
93 void *userdata;
94 pa_defer_event_destroy_cb_t destroy_callback;
95
96 PA_LLIST_FIELDS(pa_defer_event);
97 };
98
99 struct pa_mainloop {
100 PA_LLIST_HEAD(pa_io_event, io_events);
101 PA_LLIST_HEAD(pa_time_event, time_events);
102 PA_LLIST_HEAD(pa_defer_event, defer_events);
103
104 unsigned n_enabled_defer_events, n_enabled_time_events, n_io_events;
105 unsigned io_events_please_scan, time_events_please_scan, defer_events_please_scan;
106
107 pa_bool_t rebuild_pollfds:1;
108 struct pollfd *pollfds;
109 unsigned max_pollfds, n_pollfds;
110
111 pa_usec_t prepared_timeout;
112 pa_time_event *cached_next_time_event;
113
114 pa_mainloop_api api;
115
116 int retval;
117 pa_bool_t quit:1;
118
119 pa_bool_t wakeup_requested:1;
120 int wakeup_pipe[2];
121 int wakeup_pipe_type;
122
123 enum {
124 STATE_PASSIVE,
125 STATE_PREPARED,
126 STATE_POLLING,
127 STATE_POLLED,
128 STATE_QUIT
129 } state;
130
131 pa_poll_func poll_func;
132 void *poll_func_userdata;
133 int poll_func_ret;
134 };
135
136 static short map_flags_to_libc(pa_io_event_flags_t flags) {
137 return (short)
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));
142 }
143
144 static pa_io_event_flags_t map_flags_from_libc(short flags) {
145 return
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);
150 }
151
152 /* IO events */
153 static pa_io_event* mainloop_io_new(
154 pa_mainloop_api *a,
155 int fd,
156 pa_io_event_flags_t events,
157 pa_io_event_cb_t callback,
158 void *userdata) {
159
160 pa_mainloop *m;
161 pa_io_event *e;
162
163 pa_assert(a);
164 pa_assert(a->userdata);
165 pa_assert(fd >= 0);
166 pa_assert(callback);
167
168 m = a->userdata;
169 pa_assert(a == &m->api);
170
171 e = pa_xnew0(pa_io_event, 1);
172 e->mainloop = m;
173
174 e->fd = fd;
175 e->events = events;
176
177 e->callback = callback;
178 e->userdata = userdata;
179
180 #ifdef OS_IS_WIN32
181 {
182 fd_set xset;
183 struct timeval tv;
184
185 tv.tv_sec = 0;
186 tv.tv_usec = 0;
187
188 FD_ZERO (&xset);
189 FD_SET (fd, &xset);
190
191 if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
192 SELECT_TYPE_ARG5 &tv) == -1) &&
193 (WSAGetLastError() == WSAENOTSOCK)) {
194 pa_log_warn("Cannot monitor non-socket file descriptors.");
195 e->dead = TRUE;
196 }
197 }
198 #endif
199
200 PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
201 m->rebuild_pollfds = TRUE;
202 m->n_io_events ++;
203
204 pa_mainloop_wakeup(m);
205
206 return e;
207 }
208
209 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
210 pa_assert(e);
211 pa_assert(!e->dead);
212
213 if (e->events == events)
214 return;
215
216 e->events = events;
217
218 if (e->pollfd)
219 e->pollfd->events = map_flags_to_libc(events);
220 else
221 e->mainloop->rebuild_pollfds = TRUE;
222
223 pa_mainloop_wakeup(e->mainloop);
224 }
225
226 static void mainloop_io_free(pa_io_event *e) {
227 pa_assert(e);
228 pa_assert(!e->dead);
229
230 e->dead = TRUE;
231 e->mainloop->io_events_please_scan ++;
232
233 e->mainloop->n_io_events --;
234 e->mainloop->rebuild_pollfds = TRUE;
235
236 pa_mainloop_wakeup(e->mainloop);
237 }
238
239 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
240 pa_assert(e);
241
242 e->destroy_callback = callback;
243 }
244
245 /* Defer events */
246 static pa_defer_event* mainloop_defer_new(
247 pa_mainloop_api *a,
248 pa_defer_event_cb_t callback,
249 void *userdata) {
250
251 pa_mainloop *m;
252 pa_defer_event *e;
253
254 pa_assert(a);
255 pa_assert(a->userdata);
256 pa_assert(callback);
257
258 m = a->userdata;
259 pa_assert(a == &m->api);
260
261 e = pa_xnew0(pa_defer_event, 1);
262 e->mainloop = m;
263
264 e->enabled = TRUE;
265 m->n_enabled_defer_events++;
266
267 e->callback = callback;
268 e->userdata = userdata;
269
270 PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
271
272 pa_mainloop_wakeup(e->mainloop);
273
274 return e;
275 }
276
277 static void mainloop_defer_enable(pa_defer_event *e, int b) {
278 pa_assert(e);
279 pa_assert(!e->dead);
280
281 if (e->enabled && !b) {
282 pa_assert(e->mainloop->n_enabled_defer_events > 0);
283 e->mainloop->n_enabled_defer_events--;
284 } else if (!e->enabled && b) {
285 e->mainloop->n_enabled_defer_events++;
286 pa_mainloop_wakeup(e->mainloop);
287 }
288
289 e->enabled = b;
290 }
291
292 static void mainloop_defer_free(pa_defer_event *e) {
293 pa_assert(e);
294 pa_assert(!e->dead);
295
296 e->dead = TRUE;
297 e->mainloop->defer_events_please_scan ++;
298
299 if (e->enabled) {
300 pa_assert(e->mainloop->n_enabled_defer_events > 0);
301 e->mainloop->n_enabled_defer_events--;
302 e->enabled = FALSE;
303 }
304 }
305
306 static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
307 pa_assert(e);
308 pa_assert(!e->dead);
309
310 e->destroy_callback = callback;
311 }
312
313 /* Time events */
314 static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) {
315 struct timeval ttv;
316
317 if (!tv) {
318 *use_rtclock = FALSE;
319 return PA_USEC_INVALID;
320 }
321
322 ttv = *tv;
323 *use_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
324
325 if (*use_rtclock)
326 ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
327 else
328 pa_rtclock_from_wallclock(&ttv);
329
330 return pa_timeval_load(&ttv);
331 }
332
333 static pa_time_event* mainloop_time_new(
334 pa_mainloop_api *a,
335 const struct timeval *tv,
336 pa_time_event_cb_t callback,
337 void *userdata) {
338
339 pa_mainloop *m;
340 pa_time_event *e;
341 pa_usec_t t;
342 pa_bool_t use_rtclock = FALSE;
343
344 pa_assert(a);
345 pa_assert(a->userdata);
346 pa_assert(callback);
347
348 t = make_rt(tv, &use_rtclock);
349
350 m = a->userdata;
351 pa_assert(a == &m->api);
352
353 e = pa_xnew0(pa_time_event, 1);
354 e->mainloop = m;
355
356 if ((e->enabled = (t != PA_USEC_INVALID))) {
357 e->time = t;
358 e->use_rtclock = use_rtclock;
359
360 m->n_enabled_time_events++;
361
362 if (m->cached_next_time_event) {
363 pa_assert(m->cached_next_time_event->enabled);
364
365 if (t < m->cached_next_time_event->time)
366 m->cached_next_time_event = e;
367 }
368 }
369
370 e->callback = callback;
371 e->userdata = userdata;
372
373 PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
374
375 if (e->enabled)
376 pa_mainloop_wakeup(m);
377
378 return e;
379 }
380
381 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
382 pa_bool_t valid;
383 pa_usec_t t;
384 pa_bool_t use_rtclock = FALSE;
385
386 pa_assert(e);
387 pa_assert(!e->dead);
388
389 t = make_rt(tv, &use_rtclock);
390
391 valid = (t != PA_USEC_INVALID);
392 if (e->enabled && !valid) {
393 pa_assert(e->mainloop->n_enabled_time_events > 0);
394 e->mainloop->n_enabled_time_events--;
395 } else if (!e->enabled && valid)
396 e->mainloop->n_enabled_time_events++;
397
398 if ((e->enabled = valid)) {
399 e->time = t;
400 e->use_rtclock = use_rtclock;
401 pa_mainloop_wakeup(e->mainloop);
402 }
403
404 if (e->mainloop->cached_next_time_event && e->enabled) {
405 pa_assert(e->mainloop->cached_next_time_event->enabled);
406
407 if (t < e->mainloop->cached_next_time_event->time)
408 e->mainloop->cached_next_time_event = e;
409 } else if (e->mainloop->cached_next_time_event == e)
410 e->mainloop->cached_next_time_event = NULL;
411 }
412
413 static void mainloop_time_free(pa_time_event *e) {
414 pa_assert(e);
415 pa_assert(!e->dead);
416
417 e->dead = TRUE;
418 e->mainloop->time_events_please_scan ++;
419
420 if (e->enabled) {
421 pa_assert(e->mainloop->n_enabled_time_events > 0);
422 e->mainloop->n_enabled_time_events--;
423 e->enabled = FALSE;
424 }
425
426 if (e->mainloop->cached_next_time_event == e)
427 e->mainloop->cached_next_time_event = NULL;
428
429 /* no wakeup needed here. Think about it! */
430 }
431
432 static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
433 pa_assert(e);
434 pa_assert(!e->dead);
435
436 e->destroy_callback = callback;
437 }
438
439 /* quit() */
440
441 static void mainloop_quit(pa_mainloop_api *a, int retval) {
442 pa_mainloop *m;
443
444 pa_assert(a);
445 pa_assert(a->userdata);
446 m = a->userdata;
447 pa_assert(a == &m->api);
448
449 pa_mainloop_quit(m, retval);
450 }
451
452 static const pa_mainloop_api vtable = {
453 .userdata = NULL,
454
455 .io_new = mainloop_io_new,
456 .io_enable = mainloop_io_enable,
457 .io_free = mainloop_io_free,
458 .io_set_destroy = mainloop_io_set_destroy,
459
460 .time_new = mainloop_time_new,
461 .time_restart = mainloop_time_restart,
462 .time_free = mainloop_time_free,
463 .time_set_destroy = mainloop_time_set_destroy,
464
465 .defer_new = mainloop_defer_new,
466 .defer_enable = mainloop_defer_enable,
467 .defer_free = mainloop_defer_free,
468 .defer_set_destroy = mainloop_defer_set_destroy,
469
470 .quit = mainloop_quit,
471 };
472
473 pa_mainloop *pa_mainloop_new(void) {
474 pa_mainloop *m;
475
476 pa_init_i18n();
477
478 m = pa_xnew0(pa_mainloop, 1);
479
480 if (pa_pipe_cloexec(m->wakeup_pipe) < 0) {
481 pa_log_error("ERROR: cannot create wakeup pipe");
482 pa_xfree(m);
483 return NULL;
484 }
485
486 pa_make_fd_nonblock(m->wakeup_pipe[0]);
487 pa_make_fd_nonblock(m->wakeup_pipe[1]);
488
489 m->rebuild_pollfds = TRUE;
490
491 m->api = vtable;
492 m->api.userdata = m;
493
494 m->state = STATE_PASSIVE;
495
496 m->poll_func_ret = -1;
497
498 return m;
499 }
500
501 static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
502 pa_io_event *e, *n;
503
504 PA_LLIST_FOREACH_SAFE(e, n, m->io_events) {
505
506 if (!force && m->io_events_please_scan <= 0)
507 break;
508
509 if (force || e->dead) {
510 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
511
512 if (e->dead) {
513 pa_assert(m->io_events_please_scan > 0);
514 m->io_events_please_scan--;
515 }
516
517 if (e->destroy_callback)
518 e->destroy_callback(&m->api, e, e->userdata);
519
520 pa_xfree(e);
521
522 m->rebuild_pollfds = TRUE;
523 }
524 }
525
526 pa_assert(m->io_events_please_scan == 0);
527 }
528
529 static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
530 pa_time_event *e, *n;
531
532 PA_LLIST_FOREACH_SAFE(e, n, m->time_events) {
533
534 if (!force && m->time_events_please_scan <= 0)
535 break;
536
537 if (force || e->dead) {
538 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
539
540 if (e->dead) {
541 pa_assert(m->time_events_please_scan > 0);
542 m->time_events_please_scan--;
543 }
544
545 if (!e->dead && e->enabled) {
546 pa_assert(m->n_enabled_time_events > 0);
547 m->n_enabled_time_events--;
548 e->enabled = FALSE;
549 }
550
551 if (e->destroy_callback)
552 e->destroy_callback(&m->api, e, e->userdata);
553
554 pa_xfree(e);
555 }
556 }
557
558 pa_assert(m->time_events_please_scan == 0);
559 }
560
561 static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
562 pa_defer_event *e, *n;
563
564 PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) {
565
566 if (!force && m->defer_events_please_scan <= 0)
567 break;
568
569 if (force || e->dead) {
570 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
571
572 if (e->dead) {
573 pa_assert(m->defer_events_please_scan > 0);
574 m->defer_events_please_scan--;
575 }
576
577 if (!e->dead && e->enabled) {
578 pa_assert(m->n_enabled_defer_events > 0);
579 m->n_enabled_defer_events--;
580 e->enabled = FALSE;
581 }
582
583 if (e->destroy_callback)
584 e->destroy_callback(&m->api, e, e->userdata);
585
586 pa_xfree(e);
587 }
588 }
589
590 pa_assert(m->defer_events_please_scan == 0);
591 }
592
593
594 void pa_mainloop_free(pa_mainloop *m) {
595 pa_assert(m);
596
597 cleanup_io_events(m, TRUE);
598 cleanup_defer_events(m, TRUE);
599 cleanup_time_events(m, TRUE);
600
601 pa_xfree(m->pollfds);
602
603 pa_close_pipe(m->wakeup_pipe);
604
605 pa_xfree(m);
606 }
607
608 static void scan_dead(pa_mainloop *m) {
609 pa_assert(m);
610
611 if (m->io_events_please_scan)
612 cleanup_io_events(m, FALSE);
613
614 if (m->time_events_please_scan)
615 cleanup_time_events(m, FALSE);
616
617 if (m->defer_events_please_scan)
618 cleanup_defer_events(m, FALSE);
619 }
620
621 static void rebuild_pollfds(pa_mainloop *m) {
622 pa_io_event*e;
623 struct pollfd *p;
624 unsigned l;
625
626 l = m->n_io_events + 1;
627 if (m->max_pollfds < l) {
628 l *= 2;
629 m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
630 m->max_pollfds = l;
631 }
632
633 m->n_pollfds = 0;
634 p = m->pollfds;
635
636 if (m->wakeup_pipe[0] >= 0) {
637 m->pollfds[0].fd = m->wakeup_pipe[0];
638 m->pollfds[0].events = POLLIN;
639 m->pollfds[0].revents = 0;
640 p++;
641 m->n_pollfds++;
642 }
643
644 PA_LLIST_FOREACH(e, m->io_events) {
645 if (e->dead) {
646 e->pollfd = NULL;
647 continue;
648 }
649
650 e->pollfd = p;
651 p->fd = e->fd;
652 p->events = map_flags_to_libc(e->events);
653 p->revents = 0;
654
655 p++;
656 m->n_pollfds++;
657 }
658
659 m->rebuild_pollfds = FALSE;
660 }
661
662 static unsigned dispatch_pollfds(pa_mainloop *m) {
663 pa_io_event *e;
664 unsigned r = 0, k;
665
666 pa_assert(m->poll_func_ret > 0);
667
668 k = m->poll_func_ret;
669
670 PA_LLIST_FOREACH(e, m->io_events) {
671
672 if (k <= 0 || m->quit)
673 break;
674
675 if (e->dead || !e->pollfd || !e->pollfd->revents)
676 continue;
677
678 pa_assert(e->pollfd->fd == e->fd);
679 pa_assert(e->callback);
680
681 e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
682 e->pollfd->revents = 0;
683 r++;
684 k--;
685 }
686
687 return r;
688 }
689
690 static unsigned dispatch_defer(pa_mainloop *m) {
691 pa_defer_event *e;
692 unsigned r = 0;
693
694 if (m->n_enabled_defer_events <= 0)
695 return 0;
696
697 PA_LLIST_FOREACH(e, m->defer_events) {
698
699 if (m->quit)
700 break;
701
702 if (e->dead || !e->enabled)
703 continue;
704
705 pa_assert(e->callback);
706 e->callback(&m->api, e, e->userdata);
707 r++;
708 }
709
710 return r;
711 }
712
713 static pa_time_event* find_next_time_event(pa_mainloop *m) {
714 pa_time_event *t, *n = NULL;
715 pa_assert(m);
716
717 if (m->cached_next_time_event)
718 return m->cached_next_time_event;
719
720 PA_LLIST_FOREACH(t, m->time_events) {
721
722 if (t->dead || !t->enabled)
723 continue;
724
725 if (!n || t->time < n->time) {
726 n = t;
727
728 /* Shortcut for time == 0 */
729 if (n->time == 0)
730 break;
731 }
732 }
733
734 m->cached_next_time_event = n;
735 return n;
736 }
737
738 static pa_usec_t calc_next_timeout(pa_mainloop *m) {
739 pa_time_event *t;
740 pa_usec_t clock_now;
741
742 if (m->n_enabled_time_events <= 0)
743 return PA_USEC_INVALID;
744
745 pa_assert_se(t = find_next_time_event(m));
746
747 if (t->time <= 0)
748 return 0;
749
750 clock_now = pa_rtclock_now();
751
752 if (t->time <= clock_now)
753 return 0;
754
755 return t->time - clock_now;
756 }
757
758 static unsigned dispatch_timeout(pa_mainloop *m) {
759 pa_time_event *e;
760 pa_usec_t now;
761 unsigned r = 0;
762 pa_assert(m);
763
764 if (m->n_enabled_time_events <= 0)
765 return 0;
766
767 now = pa_rtclock_now();
768
769 PA_LLIST_FOREACH(e, m->time_events) {
770
771 if (m->quit)
772 break;
773
774 if (e->dead || !e->enabled)
775 continue;
776
777 if (e->time <= now) {
778 struct timeval tv;
779 pa_assert(e->callback);
780
781 /* Disable time event */
782 mainloop_time_restart(e, NULL);
783
784 e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata);
785
786 r++;
787 }
788 }
789
790 return r;
791 }
792
793 void pa_mainloop_wakeup(pa_mainloop *m) {
794 char c = 'W';
795 pa_assert(m);
796
797 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
798 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
799 m->wakeup_requested++;
800 }
801 }
802
803 static void clear_wakeup(pa_mainloop *m) {
804 char c[10];
805
806 pa_assert(m);
807
808 if (m->wakeup_pipe[0] < 0)
809 return;
810
811 if (m->wakeup_requested) {
812 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c))
813 ;
814 m->wakeup_requested = 0;
815 }
816 }
817
818 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
819 pa_assert(m);
820 pa_assert(m->state == STATE_PASSIVE);
821
822 clear_wakeup(m);
823 scan_dead(m);
824
825 if (m->quit)
826 goto quit;
827
828 if (m->n_enabled_defer_events <= 0) {
829
830 if (m->rebuild_pollfds)
831 rebuild_pollfds(m);
832
833 m->prepared_timeout = calc_next_timeout(m);
834 if (timeout >= 0) {
835 uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC;
836
837 if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID)
838 m->prepared_timeout = timeout;
839 }
840 }
841
842 m->state = STATE_PREPARED;
843 return 0;
844
845 quit:
846 m->state = STATE_QUIT;
847 return -2;
848 }
849
850 static int usec_to_timeout(pa_usec_t u) {
851 int timeout;
852
853 if (u == PA_USEC_INVALID)
854 return -1;
855
856 timeout = (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
857 pa_assert(timeout >= 0);
858
859 return timeout;
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 = pa_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 }