]> code.delx.au - pulseaudio/blob - src/pulse/mainloop.c
Merge remote branch 'origin/master-tx'
[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 (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
496 m->rebuild_pollfds = TRUE;
497
498 m->api = vtable;
499 m->api.userdata = m;
500
501 m->state = STATE_PASSIVE;
502
503 m->poll_func_ret = -1;
504
505 return m;
506 }
507
508 static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) {
509 pa_io_event *e, *n;
510
511 PA_LLIST_FOREACH_SAFE(e, n, m->io_events) {
512
513 if (!force && m->io_events_please_scan <= 0)
514 break;
515
516 if (force || e->dead) {
517 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
518
519 if (e->dead) {
520 pa_assert(m->io_events_please_scan > 0);
521 m->io_events_please_scan--;
522 }
523
524 if (e->destroy_callback)
525 e->destroy_callback(&m->api, e, e->userdata);
526
527 pa_xfree(e);
528
529 m->rebuild_pollfds = TRUE;
530 }
531 }
532
533 pa_assert(m->io_events_please_scan == 0);
534 }
535
536 static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) {
537 pa_time_event *e, *n;
538
539 PA_LLIST_FOREACH_SAFE(e, n, m->time_events) {
540
541 if (!force && m->time_events_please_scan <= 0)
542 break;
543
544 if (force || e->dead) {
545 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
546
547 if (e->dead) {
548 pa_assert(m->time_events_please_scan > 0);
549 m->time_events_please_scan--;
550 }
551
552 if (!e->dead && e->enabled) {
553 pa_assert(m->n_enabled_time_events > 0);
554 m->n_enabled_time_events--;
555 e->enabled = FALSE;
556 }
557
558 if (e->destroy_callback)
559 e->destroy_callback(&m->api, e, e->userdata);
560
561 pa_xfree(e);
562 }
563 }
564
565 pa_assert(m->time_events_please_scan == 0);
566 }
567
568 static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) {
569 pa_defer_event *e, *n;
570
571 PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) {
572
573 if (!force && m->defer_events_please_scan <= 0)
574 break;
575
576 if (force || e->dead) {
577 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
578
579 if (e->dead) {
580 pa_assert(m->defer_events_please_scan > 0);
581 m->defer_events_please_scan--;
582 }
583
584 if (!e->dead && e->enabled) {
585 pa_assert(m->n_enabled_defer_events > 0);
586 m->n_enabled_defer_events--;
587 e->enabled = FALSE;
588 }
589
590 if (e->destroy_callback)
591 e->destroy_callback(&m->api, e, e->userdata);
592
593 pa_xfree(e);
594 }
595 }
596
597 pa_assert(m->defer_events_please_scan == 0);
598 }
599
600
601 void pa_mainloop_free(pa_mainloop* m) {
602 pa_assert(m);
603
604 cleanup_io_events(m, TRUE);
605 cleanup_defer_events(m, TRUE);
606 cleanup_time_events(m, TRUE);
607
608 pa_xfree(m->pollfds);
609
610 pa_close_pipe(m->wakeup_pipe);
611
612 pa_xfree(m);
613 }
614
615 static void scan_dead(pa_mainloop *m) {
616 pa_assert(m);
617
618 if (m->io_events_please_scan)
619 cleanup_io_events(m, FALSE);
620
621 if (m->time_events_please_scan)
622 cleanup_time_events(m, FALSE);
623
624 if (m->defer_events_please_scan)
625 cleanup_defer_events(m, FALSE);
626 }
627
628 static void rebuild_pollfds(pa_mainloop *m) {
629 pa_io_event*e;
630 struct pollfd *p;
631 unsigned l;
632
633 l = m->n_io_events + 1;
634 if (m->max_pollfds < l) {
635 l *= 2;
636 m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
637 m->max_pollfds = l;
638 }
639
640 m->n_pollfds = 0;
641 p = m->pollfds;
642
643 if (m->wakeup_pipe[0] >= 0) {
644 m->pollfds[0].fd = m->wakeup_pipe[0];
645 m->pollfds[0].events = POLLIN;
646 m->pollfds[0].revents = 0;
647 p++;
648 m->n_pollfds++;
649 }
650
651 PA_LLIST_FOREACH(e, m->io_events) {
652 if (e->dead) {
653 e->pollfd = NULL;
654 continue;
655 }
656
657 e->pollfd = p;
658 p->fd = e->fd;
659 p->events = map_flags_to_libc(e->events);
660 p->revents = 0;
661
662 p++;
663 m->n_pollfds++;
664 }
665
666 m->rebuild_pollfds = FALSE;
667 }
668
669 static unsigned dispatch_pollfds(pa_mainloop *m) {
670 pa_io_event *e;
671 unsigned r = 0, k;
672
673 pa_assert(m->poll_func_ret > 0);
674
675 k = m->poll_func_ret;
676
677 PA_LLIST_FOREACH(e, m->io_events) {
678
679 if (k <= 0 || m->quit)
680 break;
681
682 if (e->dead || !e->pollfd || !e->pollfd->revents)
683 continue;
684
685 pa_assert(e->pollfd->fd == e->fd);
686 pa_assert(e->callback);
687
688 e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
689 e->pollfd->revents = 0;
690 r++;
691 k--;
692 }
693
694 return r;
695 }
696
697 static unsigned dispatch_defer(pa_mainloop *m) {
698 pa_defer_event *e;
699 unsigned r = 0;
700
701 if (m->n_enabled_defer_events <= 0)
702 return 0;
703
704 PA_LLIST_FOREACH(e, m->defer_events) {
705
706 if (m->quit)
707 break;
708
709 if (e->dead || !e->enabled)
710 continue;
711
712 pa_assert(e->callback);
713 e->callback(&m->api, e, e->userdata);
714 r++;
715 }
716
717 return r;
718 }
719
720 static pa_time_event* find_next_time_event(pa_mainloop *m) {
721 pa_time_event *t, *n = NULL;
722 pa_assert(m);
723
724 if (m->cached_next_time_event)
725 return m->cached_next_time_event;
726
727 PA_LLIST_FOREACH(t, m->time_events) {
728
729 if (t->dead || !t->enabled)
730 continue;
731
732 if (!n || t->time < n->time) {
733 n = t;
734
735 /* Shortcut for time == 0 */
736 if (n->time == 0)
737 break;
738 }
739 }
740
741 m->cached_next_time_event = n;
742 return n;
743 }
744
745 static pa_usec_t calc_next_timeout(pa_mainloop *m) {
746 pa_time_event *t;
747 pa_usec_t clock_now;
748
749 if (m->n_enabled_time_events <= 0)
750 return PA_USEC_INVALID;
751
752 pa_assert_se(t = find_next_time_event(m));
753
754 if (t->time <= 0)
755 return 0;
756
757 clock_now = pa_rtclock_now();
758
759 if (t->time <= clock_now)
760 return 0;
761
762 return t->time - clock_now;
763 }
764
765 static unsigned dispatch_timeout(pa_mainloop *m) {
766 pa_time_event *e;
767 pa_usec_t now;
768 unsigned r = 0;
769 pa_assert(m);
770
771 if (m->n_enabled_time_events <= 0)
772 return 0;
773
774 now = pa_rtclock_now();
775
776 PA_LLIST_FOREACH(e, m->time_events) {
777
778 if (m->quit)
779 break;
780
781 if (e->dead || !e->enabled)
782 continue;
783
784 if (e->time <= now) {
785 struct timeval tv;
786 pa_assert(e->callback);
787
788 /* Disable time event */
789 mainloop_time_restart(e, NULL);
790
791 e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata);
792
793 r++;
794 }
795 }
796
797 return r;
798 }
799
800 void pa_mainloop_wakeup(pa_mainloop *m) {
801 char c = 'W';
802 pa_assert(m);
803
804 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
805 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
806 m->wakeup_requested++;
807 }
808 }
809
810 static void clear_wakeup(pa_mainloop *m) {
811 char c[10];
812
813 pa_assert(m);
814
815 if (m->wakeup_pipe[0] < 0)
816 return;
817
818 if (m->wakeup_requested) {
819 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c))
820 ;
821 m->wakeup_requested = 0;
822 }
823 }
824
825 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
826 pa_assert(m);
827 pa_assert(m->state == STATE_PASSIVE);
828
829 clear_wakeup(m);
830 scan_dead(m);
831
832 if (m->quit)
833 goto quit;
834
835 if (m->n_enabled_defer_events <= 0) {
836
837 if (m->rebuild_pollfds)
838 rebuild_pollfds(m);
839
840 m->prepared_timeout = calc_next_timeout(m);
841 if (timeout >= 0) {
842 uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC;
843
844 if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID)
845 m->prepared_timeout = timeout;
846 }
847 }
848
849 m->state = STATE_PREPARED;
850 return 0;
851
852 quit:
853 m->state = STATE_QUIT;
854 return -2;
855 }
856
857 static int usec_to_timeout(pa_usec_t u) {
858 if (u == PA_USEC_INVALID)
859 return -1;
860
861 return (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC;
862 }
863
864 int pa_mainloop_poll(pa_mainloop *m) {
865 pa_assert(m);
866 pa_assert(m->state == STATE_PREPARED);
867
868 if (m->quit)
869 goto quit;
870
871 m->state = STATE_POLLING;
872
873 if (m->n_enabled_defer_events )
874 m->poll_func_ret = 0;
875 else {
876 pa_assert(!m->rebuild_pollfds);
877
878 if (m->poll_func)
879 m->poll_func_ret = m->poll_func(
880 m->pollfds, m->n_pollfds,
881 usec_to_timeout(m->prepared_timeout),
882 m->poll_func_userdata);
883 else {
884 #ifdef HAVE_PPOLL
885 struct timespec ts;
886
887 m->poll_func_ret = ppoll(
888 m->pollfds, m->n_pollfds,
889 m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout),
890 NULL);
891 #else
892 m->poll_func_ret = poll(
893 m->pollfds, m->n_pollfds,
894 usec_to_timeout(m->prepared_timeout));
895 #endif
896 }
897
898 if (m->poll_func_ret < 0) {
899 if (errno == EINTR)
900 m->poll_func_ret = 0;
901 else
902 pa_log("poll(): %s", pa_cstrerror(errno));
903 }
904 }
905
906 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
907 return m->poll_func_ret;
908
909 quit:
910 m->state = STATE_QUIT;
911 return -2;
912 }
913
914 int pa_mainloop_dispatch(pa_mainloop *m) {
915 unsigned dispatched = 0;
916
917 pa_assert(m);
918 pa_assert(m->state == STATE_POLLED);
919
920 if (m->quit)
921 goto quit;
922
923 if (m->n_enabled_defer_events)
924 dispatched += dispatch_defer(m);
925 else {
926 if (m->n_enabled_time_events)
927 dispatched += dispatch_timeout(m);
928
929 if (m->quit)
930 goto quit;
931
932 if (m->poll_func_ret > 0)
933 dispatched += dispatch_pollfds(m);
934 }
935
936 if (m->quit)
937 goto quit;
938
939 m->state = STATE_PASSIVE;
940
941 return (int) dispatched;
942
943 quit:
944 m->state = STATE_QUIT;
945 return -2;
946 }
947
948 int pa_mainloop_get_retval(pa_mainloop *m) {
949 pa_assert(m);
950
951 return m->retval;
952 }
953
954 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
955 int r;
956 pa_assert(m);
957
958 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
959 goto quit;
960
961 if ((r = pa_mainloop_poll(m)) < 0)
962 goto quit;
963
964 if ((r = pa_mainloop_dispatch(m)) < 0)
965 goto quit;
966
967 return r;
968
969 quit:
970
971 if ((r == -2) && retval)
972 *retval = pa_mainloop_get_retval(m);
973 return r;
974 }
975
976 int pa_mainloop_run(pa_mainloop *m, int *retval) {
977 int r;
978
979 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0)
980 ;
981
982 if (r == -2)
983 return 1;
984 else if (r < 0)
985 return -1;
986 else
987 return 0;
988 }
989
990 void pa_mainloop_quit(pa_mainloop *m, int retval) {
991 pa_assert(m);
992
993 m->quit = TRUE;
994 m->retval = retval;
995 pa_mainloop_wakeup(m);
996 }
997
998 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
999 pa_assert(m);
1000
1001 return &m->api;
1002 }
1003
1004 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
1005 pa_assert(m);
1006
1007 m->poll_func = poll_func;
1008 m->poll_func_userdata = userdata;
1009 }
1010
1011 pa_bool_t pa_mainloop_is_our_api(pa_mainloop_api*m) {
1012 pa_assert(m);
1013
1014 return m->io_new == mainloop_io_new;
1015 }