]> code.delx.au - pulseaudio/blob - src/pulse/mainloop.c
remove all occurences of
[pulseaudio] / src / pulse / mainloop.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdio.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32 #include <fcntl.h>
33 #include <errno.h>
34
35 #ifdef HAVE_SYS_POLL_H
36 #include <sys/poll.h>
37 #else
38 #include "../pulsecore/poll.h"
39 #endif
40
41 #include "../pulsecore/winsock.h"
42
43 #ifndef HAVE_PIPE
44 #include "../pulsecore/pipe.h"
45 #endif
46
47 #include <pulsecore/core-error.h>
48 #include <pulse/timeval.h>
49 #include <pulse/xmalloc.h>
50
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/llist.h>
53 #include <pulsecore/log.h>
54
55 #include "mainloop.h"
56
57 struct pa_io_event {
58 pa_mainloop *mainloop;
59 int dead;
60
61 int fd;
62 pa_io_event_flags_t events;
63 struct pollfd *pollfd;
64
65 pa_io_event_cb_t callback;
66 void *userdata;
67 pa_io_event_destroy_cb_t destroy_callback;
68
69 PA_LLIST_FIELDS(pa_io_event);
70 };
71
72 struct pa_time_event {
73 pa_mainloop *mainloop;
74 int dead;
75
76 int enabled;
77 struct timeval timeval;
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 int dead;
89
90 int enabled;
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 int n_enabled_defer_events, n_enabled_time_events, n_io_events;
105 int io_events_please_scan, time_events_please_scan, defer_events_please_scan;
106
107 struct pollfd *pollfds;
108 unsigned max_pollfds, n_pollfds;
109 int rebuild_pollfds;
110
111 int prepared_timeout;
112 pa_time_event *cached_next_time_event;
113
114 int quit, retval;
115 pa_mainloop_api api;
116
117 int wakeup_pipe[2];
118 int wakeup_pipe_type;
119 int wakeup_requested;
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
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 assert(a);
162 assert(a->userdata);
163 assert(fd >= 0);
164 assert(callback);
165
166 m = a->userdata;
167 assert(a == &m->api);
168
169 e = pa_xnew(pa_io_event, 1);
170 e->mainloop = m;
171 e->dead = 0;
172
173 e->fd = fd;
174 e->events = events;
175 e->pollfd = NULL;
176
177 e->callback = callback;
178 e->userdata = userdata;
179 e->destroy_callback = NULL;
180
181 #ifdef OS_IS_WIN32
182 {
183 fd_set xset;
184 struct timeval tv;
185
186 tv.tv_sec = 0;
187 tv.tv_usec = 0;
188
189 FD_ZERO (&xset);
190 FD_SET (fd, &xset);
191
192 if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
193 SELECT_TYPE_ARG5 &tv) == -1) &&
194 (WSAGetLastError() == WSAENOTSOCK)) {
195 pa_log_warn("WARNING: cannot monitor non-socket file descriptors.");
196 e->dead = 1;
197 }
198 }
199 #endif
200
201 PA_LLIST_PREPEND(pa_io_event, m->io_events, e);
202 m->rebuild_pollfds = 1;
203 m->n_io_events ++;
204
205 pa_mainloop_wakeup(m);
206
207 return e;
208 }
209
210 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
211 assert(e);
212 assert(!e->dead);
213
214 if (e->events == events)
215 return;
216
217 e->events = events;
218
219 if (e->pollfd)
220 e->pollfd->events = map_flags_to_libc(events);
221 else
222 e->mainloop->rebuild_pollfds = 1;
223
224 pa_mainloop_wakeup(e->mainloop);
225 }
226
227 static void mainloop_io_free(pa_io_event *e) {
228 assert(e);
229 assert(!e->dead);
230
231 e->dead = 1;
232 e->mainloop->io_events_please_scan ++;
233
234 e->mainloop->n_io_events --;
235 e->mainloop->rebuild_pollfds = 1;
236
237 pa_mainloop_wakeup(e->mainloop);
238 }
239
240 static void mainloop_io_set_destroy(pa_io_event *e, pa_io_event_destroy_cb_t callback) {
241 assert(e);
242
243 e->destroy_callback = callback;
244 }
245
246 /* Defer events */
247 static pa_defer_event* mainloop_defer_new(
248 pa_mainloop_api*a,
249 pa_defer_event_cb_t callback,
250 void *userdata) {
251
252 pa_mainloop *m;
253 pa_defer_event *e;
254
255 assert(a);
256 assert(a->userdata);
257 assert(callback);
258
259 m = a->userdata;
260 assert(a == &m->api);
261
262 e = pa_xnew(pa_defer_event, 1);
263 e->mainloop = m;
264 e->dead = 0;
265
266 e->enabled = 1;
267 m->n_enabled_defer_events++;
268
269 e->callback = callback;
270 e->userdata = userdata;
271 e->destroy_callback = NULL;
272
273 PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e);
274
275 pa_mainloop_wakeup(e->mainloop);
276
277 return e;
278 }
279
280 static void mainloop_defer_enable(pa_defer_event *e, int b) {
281 assert(e);
282 assert(!e->dead);
283
284 if (e->enabled && !b) {
285 assert(e->mainloop->n_enabled_defer_events > 0);
286 e->mainloop->n_enabled_defer_events--;
287 } else if (!e->enabled && b) {
288 e->mainloop->n_enabled_defer_events++;
289 pa_mainloop_wakeup(e->mainloop);
290 }
291
292 e->enabled = b;
293 }
294
295 static void mainloop_defer_free(pa_defer_event *e) {
296 assert(e);
297 assert(!e->dead);
298
299 e->dead = 1;
300 e->mainloop->defer_events_please_scan ++;
301
302 if (e->enabled) {
303 assert(e->mainloop->n_enabled_defer_events > 0);
304 e->mainloop->n_enabled_defer_events--;
305 }
306 }
307
308 static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy_cb_t callback) {
309 assert(e);
310 assert(!e->dead);
311
312 e->destroy_callback = callback;
313 }
314
315 /* Time events */
316 static pa_time_event* mainloop_time_new(
317 pa_mainloop_api*a,
318 const struct timeval *tv,
319 pa_time_event_cb_t callback,
320 void *userdata) {
321
322 pa_mainloop *m;
323 pa_time_event *e;
324
325 assert(a);
326 assert(a->userdata);
327 assert(callback);
328
329 m = a->userdata;
330 assert(a == &m->api);
331
332 e = pa_xnew(pa_time_event, 1);
333 e->mainloop = m;
334 e->dead = 0;
335
336 if ((e->enabled = !!tv)) {
337 e->timeval = *tv;
338
339 m->n_enabled_time_events++;
340
341 if (m->cached_next_time_event) {
342 assert(m->cached_next_time_event->enabled);
343
344 if (pa_timeval_cmp(tv, &m->cached_next_time_event->timeval) < 0)
345 m->cached_next_time_event = e;
346 }
347 }
348
349 e->callback = callback;
350 e->userdata = userdata;
351 e->destroy_callback = NULL;
352
353 PA_LLIST_PREPEND(pa_time_event, m->time_events, e);
354
355 if (e->enabled)
356 pa_mainloop_wakeup(m);
357
358 return e;
359 }
360
361 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
362 assert(e);
363 assert(!e->dead);
364
365 if (e->enabled && !tv) {
366 assert(e->mainloop->n_enabled_time_events > 0);
367 e->mainloop->n_enabled_time_events--;
368 } else if (!e->enabled && tv)
369 e->mainloop->n_enabled_time_events++;
370
371 if ((e->enabled = !!tv)) {
372 e->timeval = *tv;
373 pa_mainloop_wakeup(e->mainloop);
374 }
375
376 if (e->mainloop->cached_next_time_event && e->enabled) {
377 assert(e->mainloop->cached_next_time_event->enabled);
378
379 if (pa_timeval_cmp(tv, &e->mainloop->cached_next_time_event->timeval) < 0)
380 e->mainloop->cached_next_time_event = e;
381 } else if (e->mainloop->cached_next_time_event == e)
382 e->mainloop->cached_next_time_event = NULL;
383 }
384
385 static void mainloop_time_free(pa_time_event *e) {
386 assert(e);
387 assert(!e->dead);
388
389 e->dead = 1;
390 e->mainloop->time_events_please_scan ++;
391
392 if (e->enabled) {
393 assert(e->mainloop->n_enabled_time_events > 0);
394 e->mainloop->n_enabled_time_events--;
395 }
396
397 if (e->mainloop->cached_next_time_event == e)
398 e->mainloop->cached_next_time_event = NULL;
399
400 /* no wakeup needed here. Think about it! */
401 }
402
403 static void mainloop_time_set_destroy(pa_time_event *e, pa_time_event_destroy_cb_t callback) {
404 assert(e);
405 assert(!e->dead);
406
407 e->destroy_callback = callback;
408 }
409
410 /* quit() */
411
412 static void mainloop_quit(pa_mainloop_api*a, int retval) {
413 pa_mainloop *m;
414
415 assert(a);
416 assert(a->userdata);
417 m = a->userdata;
418 assert(a == &m->api);
419
420 pa_mainloop_quit(m, retval);
421 }
422
423 static const pa_mainloop_api vtable = {
424 .userdata = NULL,
425
426 .io_new= mainloop_io_new,
427 .io_enable= mainloop_io_enable,
428 .io_free= mainloop_io_free,
429 .io_set_destroy= mainloop_io_set_destroy,
430
431 .time_new = mainloop_time_new,
432 .time_restart = mainloop_time_restart,
433 .time_free = mainloop_time_free,
434 .time_set_destroy = mainloop_time_set_destroy,
435
436 .defer_new = mainloop_defer_new,
437 .defer_enable = mainloop_defer_enable,
438 .defer_free = mainloop_defer_free,
439 .defer_set_destroy = mainloop_defer_set_destroy,
440
441 .quit = mainloop_quit,
442 };
443
444 pa_mainloop *pa_mainloop_new(void) {
445 pa_mainloop *m;
446
447 m = pa_xnew(pa_mainloop, 1);
448
449 m->wakeup_pipe_type = 0;
450 if (pipe(m->wakeup_pipe) < 0) {
451 pa_log_error("ERROR: cannot create wakeup pipe");
452 pa_xfree(m);
453 return NULL;
454 }
455
456 pa_make_nonblock_fd(m->wakeup_pipe[0]);
457 pa_make_nonblock_fd(m->wakeup_pipe[1]);
458 m->wakeup_requested = 0;
459
460 PA_LLIST_HEAD_INIT(pa_io_event, m->io_events);
461 PA_LLIST_HEAD_INIT(pa_time_event, m->time_events);
462 PA_LLIST_HEAD_INIT(pa_defer_event, m->defer_events);
463
464 m->n_enabled_defer_events = m->n_enabled_time_events = m->n_io_events = 0;
465 m->io_events_please_scan = m->time_events_please_scan = m->defer_events_please_scan = 0;
466
467 m->cached_next_time_event = NULL;
468 m->prepared_timeout = 0;
469
470 m->pollfds = NULL;
471 m->max_pollfds = m->n_pollfds = 0;
472 m->rebuild_pollfds = 1;
473
474 m->quit = m->retval = 0;
475
476 m->api = vtable;
477 m->api.userdata = m;
478
479 m->state = STATE_PASSIVE;
480
481 m->poll_func = NULL;
482 m->poll_func_userdata = NULL;
483 m->poll_func_ret = -1;
484
485 return m;
486 }
487
488 static void cleanup_io_events(pa_mainloop *m, int force) {
489 pa_io_event *e;
490
491 e = m->io_events;
492 while (e) {
493 pa_io_event *n = e->next;
494
495 if (!force && m->io_events_please_scan <= 0)
496 break;
497
498 if (force || e->dead) {
499 PA_LLIST_REMOVE(pa_io_event, m->io_events, e);
500
501 if (e->dead) {
502 assert(m->io_events_please_scan > 0);
503 m->io_events_please_scan--;
504 }
505
506 if (e->destroy_callback)
507 e->destroy_callback(&m->api, e, e->userdata);
508
509 pa_xfree(e);
510
511 m->rebuild_pollfds = 1;
512 }
513
514 e = n;
515 }
516
517 assert(m->io_events_please_scan == 0);
518 }
519
520 static void cleanup_time_events(pa_mainloop *m, int force) {
521 pa_time_event *e;
522
523 e = m->time_events;
524 while (e) {
525 pa_time_event *n = e->next;
526
527 if (!force && m->time_events_please_scan <= 0)
528 break;
529
530 if (force || e->dead) {
531 PA_LLIST_REMOVE(pa_time_event, m->time_events, e);
532
533 if (e->dead) {
534 assert(m->time_events_please_scan > 0);
535 m->time_events_please_scan--;
536 }
537
538 if (!e->dead && e->enabled) {
539 assert(m->n_enabled_time_events > 0);
540 m->n_enabled_time_events--;
541 }
542
543 if (e->destroy_callback)
544 e->destroy_callback(&m->api, e, e->userdata);
545
546 pa_xfree(e);
547 }
548
549 e = n;
550 }
551
552 assert(m->time_events_please_scan == 0);
553 }
554
555 static void cleanup_defer_events(pa_mainloop *m, int force) {
556 pa_defer_event *e;
557
558 e = m->defer_events;
559 while (e) {
560 pa_defer_event *n = e->next;
561
562 if (!force && m->defer_events_please_scan <= 0)
563 break;
564
565 if (force || e->dead) {
566 PA_LLIST_REMOVE(pa_defer_event, m->defer_events, e);
567
568 if (e->dead) {
569 assert(m->defer_events_please_scan > 0);
570 m->defer_events_please_scan--;
571 }
572
573 if (!e->dead && e->enabled) {
574 assert(m->n_enabled_defer_events > 0);
575 m->n_enabled_defer_events--;
576 }
577
578 if (e->destroy_callback)
579 e->destroy_callback(&m->api, e, e->userdata);
580
581 pa_xfree(e);
582 }
583
584 e = n;
585 }
586
587 assert(m->defer_events_please_scan == 0);
588 }
589
590
591 void pa_mainloop_free(pa_mainloop* m) {
592 assert(m);
593
594 cleanup_io_events(m, 1);
595 cleanup_defer_events(m, 1);
596 cleanup_time_events(m, 1);
597
598 pa_xfree(m->pollfds);
599
600 if (m->wakeup_pipe[0] >= 0)
601 close(m->wakeup_pipe[0]);
602 if (m->wakeup_pipe[1] >= 0)
603 close(m->wakeup_pipe[1]);
604
605 pa_xfree(m);
606 }
607
608 static void scan_dead(pa_mainloop *m) {
609 assert(m);
610
611 if (m->io_events_please_scan)
612 cleanup_io_events(m, 0);
613
614 if (m->time_events_please_scan)
615 cleanup_time_events(m, 0);
616
617 if (m->defer_events_please_scan)
618 cleanup_defer_events(m, 0);
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 for (e = m->io_events; e; e = e->next) {
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 = 0;
660 }
661
662 static int dispatch_pollfds(pa_mainloop *m) {
663 pa_io_event *e;
664 int r = 0, k;
665
666 assert(m->poll_func_ret > 0);
667
668 for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) {
669 if (e->dead || !e->pollfd || !e->pollfd->revents)
670 continue;
671
672 assert(e->pollfd->fd == e->fd && e->callback);
673 e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata);
674 e->pollfd->revents = 0;
675 r++;
676
677 k--;
678 }
679
680 return r;
681 }
682
683 static int dispatch_defer(pa_mainloop *m) {
684 pa_defer_event *e;
685 int r = 0;
686
687 if (m->n_enabled_defer_events <= 0)
688 return 0;
689
690 for (e = m->defer_events; e && !m->quit; e = e->next) {
691 if (e->dead || !e->enabled)
692 continue;
693
694 assert(e->callback);
695 e->callback(&m->api, e, e->userdata);
696 r++;
697 }
698
699 return r;
700 }
701
702 static pa_time_event* find_next_time_event(pa_mainloop *m) {
703 pa_time_event *t, *n = NULL;
704 assert(m);
705
706 if (m->cached_next_time_event)
707 return m->cached_next_time_event;
708
709 for (t = m->time_events; t; t = t->next) {
710
711 if (t->dead || !t->enabled)
712 continue;
713
714 if (!n || pa_timeval_cmp(&t->timeval, &n->timeval) < 0) {
715 n = t;
716
717 /* Shortcut for tv = { 0, 0 } */
718 if (n->timeval.tv_sec <= 0)
719 break;
720 }
721 }
722
723 m->cached_next_time_event = n;
724 return n;
725 }
726
727 static int calc_next_timeout(pa_mainloop *m) {
728 pa_time_event *t;
729 struct timeval now;
730 pa_usec_t usec;
731
732 if (!m->n_enabled_time_events)
733 return -1;
734
735 t = find_next_time_event(m);
736 assert(t);
737
738 if (t->timeval.tv_sec <= 0)
739 return 0;
740
741 pa_gettimeofday(&now);
742
743 if (pa_timeval_cmp(&t->timeval, &now) <= 0)
744 return 0;
745
746 usec = pa_timeval_diff(&t->timeval, &now);
747 return (int) (usec / 1000);
748 }
749
750 static int dispatch_timeout(pa_mainloop *m) {
751 pa_time_event *e;
752 struct timeval now;
753 int r = 0;
754 assert(m);
755
756 if (m->n_enabled_time_events <= 0)
757 return 0;
758
759 pa_gettimeofday(&now);
760
761 for (e = m->time_events; e && !m->quit; e = e->next) {
762
763 if (e->dead || !e->enabled)
764 continue;
765
766 if (pa_timeval_cmp(&e->timeval, &now) <= 0) {
767 assert(e->callback);
768
769 /* Disable time event */
770 mainloop_time_restart(e, NULL);
771
772 e->callback(&m->api, e, &e->timeval, e->userdata);
773
774 r++;
775 }
776 }
777
778 return r;
779 }
780
781 void pa_mainloop_wakeup(pa_mainloop *m) {
782 char c = 'W';
783 assert(m);
784
785 if (m->wakeup_pipe[1] >= 0 && m->state == STATE_POLLING) {
786 pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type);
787 m->wakeup_requested++;
788 }
789 }
790
791 static void clear_wakeup(pa_mainloop *m) {
792 char c[10];
793
794 assert(m);
795
796 if (m->wakeup_pipe[0] < 0)
797 return;
798
799 if (m->wakeup_requested) {
800 while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c));
801 m->wakeup_requested = 0;
802 }
803 }
804
805 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
806 assert(m);
807 assert(m->state == STATE_PASSIVE);
808
809 clear_wakeup(m);
810 scan_dead(m);
811
812 if (m->quit)
813 goto quit;
814
815 if (m->n_enabled_defer_events <= 0) {
816 if (m->rebuild_pollfds)
817 rebuild_pollfds(m);
818
819 m->prepared_timeout = calc_next_timeout(m);
820 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
821 m->prepared_timeout = timeout;
822 }
823
824 m->state = STATE_PREPARED;
825 return 0;
826
827 quit:
828 m->state = STATE_QUIT;
829 return -2;
830 }
831
832 int pa_mainloop_poll(pa_mainloop *m) {
833 assert(m);
834 assert(m->state == STATE_PREPARED);
835
836 if (m->quit)
837 goto quit;
838
839 m->state = STATE_POLLING;
840
841 if (m->n_enabled_defer_events )
842 m->poll_func_ret = 0;
843 else {
844 assert(!m->rebuild_pollfds);
845
846 if (m->poll_func)
847 m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
848 else
849 m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
850
851 if (m->poll_func_ret < 0) {
852 if (errno == EINTR)
853 m->poll_func_ret = 0;
854 else
855 pa_log("poll(): %s", pa_cstrerror(errno));
856 }
857 }
858
859 m->state = m->poll_func_ret < 0 ? STATE_PASSIVE : STATE_POLLED;
860 return m->poll_func_ret;
861
862 quit:
863 m->state = STATE_QUIT;
864 return -2;
865 }
866
867 int pa_mainloop_dispatch(pa_mainloop *m) {
868 int dispatched = 0;
869
870 assert(m);
871 assert(m->state == STATE_POLLED);
872
873 if (m->quit)
874 goto quit;
875
876 if (m->n_enabled_defer_events)
877 dispatched += dispatch_defer(m);
878 else {
879 if (m->n_enabled_time_events)
880 dispatched += dispatch_timeout(m);
881
882 if (m->quit)
883 goto quit;
884
885 if (m->poll_func_ret > 0)
886 dispatched += dispatch_pollfds(m);
887 }
888
889 if (m->quit)
890 goto quit;
891
892 m->state = STATE_PASSIVE;
893
894 return dispatched;
895
896 quit:
897 m->state = STATE_QUIT;
898 return -2;
899 }
900
901 int pa_mainloop_get_retval(pa_mainloop *m) {
902 assert(m);
903 return m->retval;
904 }
905
906 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
907 int r;
908 assert(m);
909
910 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
911 goto quit;
912
913 if ((r = pa_mainloop_poll(m)) < 0)
914 goto quit;
915
916 if ((r = pa_mainloop_dispatch(m)) < 0)
917 goto quit;
918
919 return r;
920
921 quit:
922
923 if ((r == -2) && retval)
924 *retval = pa_mainloop_get_retval(m);
925 return r;
926 }
927
928 int pa_mainloop_run(pa_mainloop *m, int *retval) {
929 int r;
930
931 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
932
933 if (r == -2)
934 return 1;
935 else if (r < 0)
936 return -1;
937 else
938 return 0;
939 }
940
941 void pa_mainloop_quit(pa_mainloop *m, int retval) {
942 assert(m);
943
944 m->quit = 1;
945 m->retval = retval;
946 pa_mainloop_wakeup(m);
947 }
948
949 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
950 assert(m);
951 return &m->api;
952 }
953
954 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
955 assert(m);
956
957 m->poll_func = poll_func;
958 m->poll_func_userdata = userdata;
959 }