]> code.delx.au - pulseaudio/blob - src/pulse/mainloop.c
rtclock: enable rtclock for our own mainloop implementations
[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_usec_t time;
82
83 pa_time_event_cb_t callback;
84 void *userdata;
85 pa_time_event_destroy_cb_t destroy_callback;
86
87 PA_LLIST_FIELDS(pa_time_event);
88 };
89
90 struct pa_defer_event {
91 pa_mainloop *mainloop;
92 pa_bool_t dead:1;
93
94 pa_bool_t enabled:1;
95
96 pa_defer_event_cb_t callback;
97 void *userdata;
98 pa_defer_event_destroy_cb_t destroy_callback;
99
100 PA_LLIST_FIELDS(pa_defer_event);
101 };
102
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);
107
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;
110
111 pa_bool_t rebuild_pollfds:1;
112 struct pollfd *pollfds;
113 unsigned max_pollfds, n_pollfds;
114
115 int prepared_timeout;
116 pa_time_event *cached_next_time_event;
117
118 pa_mainloop_api api;
119
120 int retval;
121 pa_bool_t quit:1;
122
123 pa_bool_t wakeup_requested:1;
124 int wakeup_pipe[2];
125 int wakeup_pipe_type;
126
127 enum {
128 STATE_PASSIVE,
129 STATE_PREPARED,
130 STATE_POLLING,
131 STATE_POLLED,
132 STATE_QUIT
133 } state;
134
135 pa_poll_func poll_func;
136 void *poll_func_userdata;
137 int poll_func_ret;
138 };
139
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));
146 }
147
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);
154 }
155
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) {
163
164 pa_mainloop *m;
165 pa_io_event *e;
166
167 pa_assert(a);
168 pa_assert(a->userdata);
169 pa_assert(fd >= 0);
170 pa_assert(callback);
171
172 m = a->userdata;
173 pa_assert(a == &m->api);
174
175 e = pa_xnew(pa_io_event, 1);
176 e->mainloop = m;
177 e->dead = FALSE;
178
179 e->fd = fd;
180 e->events = events;
181 e->pollfd = NULL;
182
183 e->callback = callback;
184 e->userdata = userdata;
185 e->destroy_callback = NULL;
186
187 #ifdef OS_IS_WIN32
188 {
189 fd_set xset;
190 struct timeval tv;
191
192 tv.tv_sec = 0;
193 tv.tv_usec = 0;
194
195 FD_ZERO (&xset);
196 FD_SET (fd, &xset);
197
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;
203 }
204 }
205 #endif
206
207 PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
208 m->rebuild_pollfds = TRUE;
209 m->n_io_events ++;
210
211 pa_mainloop_wakeup(m);
212
213 return e;
214 }
215
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);
219
220 if (e->events == events)
221 return;
222
223 e->events = events;
224
225 if (e->pollfd)
226 e->pollfd->events = map_flags_to_libc(events);
227 else
228 e->mainloop->rebuild_pollfds = TRUE;
229
230 pa_mainloop_wakeup(e->mainloop);
231 }
232
233 static void mainloop_io_free(pa_io_event *e) {
234 pa_assert(e);
235 pa_assert(!e->dead);
236
237 e->dead = TRUE;
238 e->mainloop->io_events_please_scan ++;
239
240 e->mainloop->n_io_events --;
241 e->mainloop->rebuild_pollfds = TRUE;
242
243 pa_mainloop_wakeup(e->mainloop);
244 }
245
246 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
247 pa_assert(e);
248
249 e->destroy_callback = callback;
250 }
251
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) {
257
258 pa_mainloop *m;
259 pa_defer_event *e;
260
261 pa_assert(a);
262 pa_assert(a->userdata);
263 pa_assert(callback);
264
265 m = a->userdata;
266 pa_assert(a == &m->api);
267
268 e = pa_xnew(pa_defer_event, 1);
269 e->mainloop = m;
270 e->dead = FALSE;
271
272 e->enabled = TRUE;
273 m->n_enabled_defer_events++;
274
275 e->callback = callback;
276 e->userdata = userdata;
277 e->destroy_callback = NULL;
278
279 PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
280
281 pa_mainloop_wakeup(e->mainloop);
282
283 return e;
284 }
285
286 static void mainloop_defer_enable(pa_defer_event *e, int b) {
287 pa_assert(e);
288 pa_assert(!e->dead);
289
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);
296 }
297
298 e->enabled = b;
299 }
300
301 static void mainloop_defer_free(pa_defer_event *e) {
302 pa_assert(e);
303 pa_assert(!e->dead);
304
305 e->dead = TRUE;
306 e->mainloop->defer_events_please_scan ++;
307
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;
312 }
313 }
314
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);
318
319 e->destroy_callback = callback;
320 }
321
322 /* Time events */
323 static pa_usec_t timeval_load(const struct timeval *tv) {
324 pa_bool_t is_rtclock;
325 struct timeval ttv;
326
327 if (!tv)
328 return PA_USEC_INVALID;
329
330 ttv = *tv;
331 is_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK);
332 ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK;
333
334 if (!is_rtclock)
335 pa_rtclock_from_wallclock(&ttv);
336
337 return pa_timeval_load(&ttv);
338 }
339
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) {
345
346 pa_mainloop *m;
347 pa_time_event *e;
348 pa_usec_t t;
349
350 pa_assert(a);
351 pa_assert(a->userdata);
352 pa_assert(callback);
353
354 t = timeval_load(tv);
355
356 m = a->userdata;
357 pa_assert(a == &m->api);
358
359 e = pa_xnew(pa_time_event, 1);
360 e->mainloop = m;
361 e->dead = FALSE;
362
363 if ((e->enabled = (t != PA_USEC_INVALID))) {
364 e->time = t;
365
366 m->n_enabled_time_events++;
367
368 if (m->cached_next_time_event) {
369 pa_assert(m->cached_next_time_event->enabled);
370
371 if (t < m->cached_next_time_event->time)
372 m->cached_next_time_event = e;
373 }
374 }
375
376 e->callback = callback;
377 e->userdata = userdata;
378 e->destroy_callback = NULL;
379
380 PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
381
382 if (e->enabled)
383 pa_mainloop_wakeup(m);
384
385 return e;
386 }
387
388 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
389 pa_bool_t valid;
390 pa_usec_t t;
391
392 pa_assert(e);
393 pa_assert(!e->dead);
394
395 t = timeval_load(tv);
396
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++;
403
404 if ((e->enabled = valid)) {
405 e->time = t;
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_xnew(pa_mainloop, 1);
484
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;
490 }
491
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;
497
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);
501
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;
504
505 m->cached_next_time_event = NULL;
506 m->prepared_timeout = 0;
507
508 m->pollfds = NULL;
509 m->max_pollfds = m->n_pollfds = 0;
510 m->rebuild_pollfds = TRUE;
511
512 m->quit = FALSE;
513 m->retval = 0;
514
515 m->api = vtable;
516 m->api.userdata = m;
517
518 m->state = STATE_PASSIVE;
519
520 m->poll_func = NULL;
521 m->poll_func_userdata = NULL;
522 m->poll_func_ret = -1;
523
524 return m;
525 }
526
527 static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
528 pa_io_event *e;
529
530 e = m->io_events;
531 while (e) {
532 pa_io_event *n = e->next;
533
534 if (!force && m->io_events_please_scan <= 0)
535 break;
536
537 if (force || e->dead) {
538 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
539
540 if (e->dead) {
541 pa_assert(m->io_events_please_scan > 0);
542 m->io_events_please_scan--;
543 }
544
545 if (e->destroy_callback)
546 e->destroy_callback(&m->api, e, e->userdata);
547
548 pa_xfree(e);
549
550 m->rebuild_pollfds = TRUE;
551 }
552
553 e = n;
554 }
555
556 pa_assert(m->io_events_please_scan == 0);
557 }
558
559 static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
560 pa_time_event *e;
561
562 e = m->time_events;
563 while (e) {
564 pa_time_event *n = e->next;
565
566 if (!force && m->time_events_please_scan <= 0)
567 break;
568
569 if (force || e->dead) {
570 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
571
572 if (e->dead) {
573 pa_assert(m->time_events_please_scan > 0);
574 m->time_events_please_scan--;
575 }
576
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;
581 }
582
583 if (e->destroy_callback)
584 e->destroy_callback(&m->api, e, e->userdata);
585
586 pa_xfree(e);
587 }
588
589 e = n;
590 }
591
592 pa_assert(m->time_events_please_scan == 0);
593 }
594
595 static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
596 pa_defer_event *e;
597
598 e = m->defer_events;
599 while (e) {
600 pa_defer_event *n = e->next;
601
602 if (!force && m->defer_events_please_scan <= 0)
603 break;
604
605 if (force || e->dead) {
606 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
607
608 if (e->dead) {
609 pa_assert(m->defer_events_please_scan > 0);
610 m->defer_events_please_scan--;
611 }
612
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;
617 }
618
619 if (e->destroy_callback)
620 e->destroy_callback(&m->api, e, e->userdata);
621
622 pa_xfree(e);
623 }
624
625 e = n;
626 }
627
628 pa_assert(m->defer_events_please_scan == 0);
629 }
630
631
632 void pa_mainloop_free(pa_mainloop* m) {
633 pa_assert(m);
634
635 cleanup_io_events(m, TRUE);
636 cleanup_defer_events(m, TRUE);
637 cleanup_time_events(m, TRUE);
638
639 pa_xfree(m->pollfds);
640
641 pa_close_pipe(m->wakeup_pipe);
642
643 pa_xfree(m);
644 }
645
646 static void scan_dead(pa_mainloop *m) {
647 pa_assert(m);
648
649 if (m->io_events_please_scan)
650 cleanup_io_events(m, FALSE);
651
652 if (m->time_events_please_scan)
653 cleanup_time_events(m, FALSE);
654
655 if (m->defer_events_please_scan)
656 cleanup_defer_events(m, FALSE);
657 }
658
659 static void rebuild_pollfds(pa_mainloop *m) {
660 pa_io_event*e;
661 struct pollfd *p;
662 unsigned l;
663
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;
669 }
670
671 m->n_pollfds = 0;
672 p = m->pollfds;
673
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++;
680 }
681
682 for (e = m->io_events; e; e = e->next) {
683 if (e->dead) {
684 e->pollfd = NULL;
685 continue;
686 }
687
688 e->pollfd = p;
689 p->fd = e->fd;
690 p->events = map_flags_to_libc(e->events);
691 p->revents = 0;
692
693 p++;
694 m->n_pollfds++;
695 }
696
697 m->rebuild_pollfds = FALSE;
698 }
699
700 static int dispatch_pollfds(pa_mainloop *m) {
701 pa_io_event *e;
702 int r = 0, k;
703
704 pa_assert(m->poll_func_ret > 0);
705
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;
709
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++;
715
716 k--;
717 }
718
719 return r;
720 }
721
722 static int dispatch_defer(pa_mainloop *m) {
723 pa_defer_event *e;
724 int r = 0;
725
726 if (m->n_enabled_defer_events <= 0)
727 return 0;
728
729 for (e = m->defer_events; e && !m->quit; e = e->next) {
730 if (e->dead || !e->enabled)
731 continue;
732
733 pa_assert(e->callback);
734 e->callback(&m->api, e, e->userdata);
735 r++;
736 }
737
738 return r;
739 }
740
741 static pa_time_event* find_next_time_event(pa_mainloop *m) {
742 pa_time_event *t, *n = NULL;
743 pa_assert(m);
744
745 if (m->cached_next_time_event)
746 return m->cached_next_time_event;
747
748 for (t = m->time_events; t; t = t->next) {
749
750 if (t->dead || !t->enabled)
751 continue;
752
753 if (!n || t->time < n->time) {
754 n = t;
755
756 /* Shortcut for time == 0 */
757 if (n->time == 0)
758 break;
759 }
760 }
761
762 m->cached_next_time_event = n;
763 return n;
764 }
765
766 static int calc_next_timeout(pa_mainloop *m) {
767 pa_time_event *t;
768 pa_usec_t usec;
769
770 if (!m->n_enabled_time_events)
771 return -1;
772
773 t = find_next_time_event(m);
774 pa_assert(t);
775
776 if (t->time == 0)
777 return 0;
778
779 usec = t->time - pa_rtclock_now();
780
781 if (usec <= 0)
782 return 0;
783
784 return (int) (usec / 1000); /* in milliseconds */
785 }
786
787 static int dispatch_timeout(pa_mainloop *m) {
788 pa_time_event *e;
789 pa_usec_t now;
790 int r = 0;
791 pa_assert(m);
792
793 if (m->n_enabled_time_events <= 0)
794 return 0;
795
796 now = pa_rtclock_now();
797
798 for (e = m->time_events; e && !m->quit; e = e->next) {
799
800 if (e->dead || !e->enabled)
801 continue;
802
803 if (e->time <= now) {
804 struct timeval tv;
805 pa_assert(e->callback);
806
807 /* Disable time event */
808 mainloop_time_restart(e, NULL);
809
810 e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata);
811
812 r++;
813 }
814 }
815
816 return r;
817 }
818
819 void pa_mainloop_wakeup(pa_mainloop *m) {
820 char c = 'W';
821 pa_assert(m);
822
823 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
824 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
825 m->wakeup_requested++;
826 }
827 }
828
829 static void clear_wakeup(pa_mainloop *m) {
830 char c[10];
831
832 pa_assert(m);
833
834 if (m->wakeup_pipe[0] < 0)
835 return;
836
837 if (m->wakeup_requested) {
838 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c));
839 m->wakeup_requested = 0;
840 }
841 }
842
843 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
844 pa_assert(m);
845 pa_assert(m->state == STATE_PASSIVE);
846
847 clear_wakeup(m);
848 scan_dead(m);
849
850 if (m->quit)
851 goto quit;
852
853 if (m->n_enabled_defer_events <= 0) {
854 if (m->rebuild_pollfds)
855 rebuild_pollfds(m);
856
857 m->prepared_timeout = calc_next_timeout(m);
858 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
859 m->prepared_timeout = timeout;
860 }
861
862 m->state = STATE_PREPARED;
863 return 0;
864
865 quit:
866 m->state = STATE_QUIT;
867 return -2;
868 }
869
870 int pa_mainloop_poll(pa_mainloop *m) {
871 pa_assert(m);
872 pa_assert(m->state == STATE_PREPARED);
873
874 if (m->quit)
875 goto quit;
876
877 m->state = STATE_POLLING;
878
879 if (m->n_enabled_defer_events )
880 m->poll_func_ret = 0;
881 else {
882 pa_assert(!m->rebuild_pollfds);
883
884 if (m->poll_func)
885 m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
886 else
887 m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
888
889 if (m->poll_func_ret < 0) {
890 if (errno == EINTR)
891 m->poll_func_ret = 0;
892 else
893 pa_log("poll(): %s", pa_cstrerror(errno));
894 }
895 }
896
897 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
898 return m->poll_func_ret;
899
900 quit:
901 m->state = STATE_QUIT;
902 return -2;
903 }
904
905 int pa_mainloop_dispatch(pa_mainloop *m) {
906 int dispatched = 0;
907
908 pa_assert(m);
909 pa_assert(m->state == STATE_POLLED);
910
911 if (m->quit)
912 goto quit;
913
914 if (m->n_enabled_defer_events)
915 dispatched += dispatch_defer(m);
916 else {
917 if (m->n_enabled_time_events)
918 dispatched += dispatch_timeout(m);
919
920 if (m->quit)
921 goto quit;
922
923 if (m->poll_func_ret > 0)
924 dispatched += dispatch_pollfds(m);
925 }
926
927 if (m->quit)
928 goto quit;
929
930 m->state = STATE_PASSIVE;
931
932 return dispatched;
933
934 quit:
935 m->state = STATE_QUIT;
936 return -2;
937 }
938
939 int pa_mainloop_get_retval(pa_mainloop *m) {
940 pa_assert(m);
941 return m->retval;
942 }
943
944 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
945 int r;
946 pa_assert(m);
947
948 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
949 goto quit;
950
951 if ((r = pa_mainloop_poll(m)) < 0)
952 goto quit;
953
954 if ((r = pa_mainloop_dispatch(m)) < 0)
955 goto quit;
956
957 return r;
958
959 quit:
960
961 if ((r == -2) && retval)
962 *retval = pa_mainloop_get_retval(m);
963 return r;
964 }
965
966 int pa_mainloop_run(pa_mainloop *m, int *retval) {
967 int r;
968
969 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
970
971 if (r == -2)
972 return 1;
973 else if (r < 0)
974 return -1;
975 else
976 return 0;
977 }
978
979 void pa_mainloop_quit(pa_mainloop *m, int retval) {
980 pa_assert(m);
981
982 m->quit = TRUE;
983 m->retval = retval;
984 pa_mainloop_wakeup(m);
985 }
986
987 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
988 pa_assert(m);
989 return &m->api;
990 }
991
992 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
993 pa_assert(m);
994
995 m->poll_func = poll_func;
996 m->poll_func_userdata = userdata;
997 }
998
999 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
1000 pa_assert(m);
1001
1002 return m->io_new == mainloop_io_new;
1003 }