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