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