]> code.delx.au - pulseaudio/blob - src/polyp/mainloop.c
add new API to replace the poll() function used by the main loop implementation
[pulseaudio] / src / polyp / mainloop.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio 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 polypaudio 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 polypaudio; 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 "../polypcore/poll.h"
39 #endif
40
41 #include "../polypcore/winsock.h"
42
43 #include <polypcore/util.h>
44 #include <polypcore/idxset.h>
45 #include <polypcore/xmalloc.h>
46 #include <polypcore/log.h>
47
48 #include "mainloop.h"
49
50 struct pa_io_event {
51 pa_mainloop *mainloop;
52 int dead;
53 int fd;
54 pa_io_event_flags_t events;
55 void (*callback) (pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata);
56 struct pollfd *pollfd;
57 void *userdata;
58 void (*destroy_callback) (pa_mainloop_api*a, pa_io_event *e, void *userdata);
59 };
60
61 struct pa_time_event {
62 pa_mainloop *mainloop;
63 int dead;
64 int enabled;
65 struct timeval timeval;
66 void (*callback)(pa_mainloop_api*a, pa_time_event *e, const struct timeval*tv, void *userdata);
67 void *userdata;
68 void (*destroy_callback) (pa_mainloop_api*a, pa_time_event *e, void *userdata);
69 };
70
71 struct pa_defer_event {
72 pa_mainloop *mainloop;
73 int dead;
74 int enabled;
75 void (*callback)(pa_mainloop_api*a, pa_defer_event*e, void *userdata);
76 void *userdata;
77 void (*destroy_callback) (pa_mainloop_api*a, pa_defer_event *e, void *userdata);
78 };
79
80 struct pa_mainloop {
81 pa_idxset *io_events, *time_events, *defer_events;
82 int io_events_scan_dead, defer_events_scan_dead, time_events_scan_dead;
83
84 struct pollfd *pollfds;
85 unsigned max_pollfds, n_pollfds;
86 int rebuild_pollfds;
87
88 int prepared_timeout;
89
90 int quit, retval;
91 pa_mainloop_api api;
92
93 int deferred_pending;
94
95 int wakeup_pipe[2];
96
97 enum {
98 STATE_PASSIVE,
99 STATE_PREPARED,
100 STATE_POLLING,
101 STATE_POLLED,
102 STATE_QUIT
103 } state;
104
105 pa_poll_func poll_func;
106 void *poll_func_userdata;
107 };
108
109 /* IO events */
110 static pa_io_event* mainloop_io_new(
111 pa_mainloop_api*a,
112 int fd,
113 pa_io_event_flags_t events,
114 void (*callback) (pa_mainloop_api*a, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata),
115 void *userdata) {
116
117 pa_mainloop *m;
118 pa_io_event *e;
119
120 assert(a && a->userdata && fd >= 0 && callback);
121 m = a->userdata;
122 assert(a == &m->api);
123
124 pa_mainloop_wakeup(m);
125
126 e = pa_xmalloc(sizeof(pa_io_event));
127 e->mainloop = m;
128 e->dead = 0;
129
130 e->fd = fd;
131 e->events = events;
132 e->callback = callback;
133 e->userdata = userdata;
134 e->destroy_callback = NULL;
135 e->pollfd = NULL;
136
137 #ifdef OS_IS_WIN32
138 {
139 fd_set xset;
140 struct timeval tv;
141
142 tv.tv_sec = 0;
143 tv.tv_usec = 0;
144
145 FD_ZERO (&xset);
146 FD_SET (fd, &xset);
147
148 if ((select((SELECT_TYPE_ARG1) fd, NULL, NULL, SELECT_TYPE_ARG234 &xset,
149 SELECT_TYPE_ARG5 &tv) == -1) &&
150 (WSAGetLastError() == WSAENOTSOCK)) {
151 pa_log_warn(__FILE__": WARNING: cannot monitor non-socket file descriptors.");
152 e->dead = 1;
153 }
154 }
155 #endif
156
157 pa_idxset_put(m->io_events, e, NULL);
158 m->rebuild_pollfds = 1;
159 return e;
160 }
161
162 static void mainloop_io_enable(pa_io_event *e, pa_io_event_flags_t events) {
163 assert(e && e->mainloop);
164
165 pa_mainloop_wakeup(e->mainloop);
166
167 e->events = events;
168 e->mainloop->rebuild_pollfds = 1;
169 }
170
171 static void mainloop_io_free(pa_io_event *e) {
172 assert(e && e->mainloop);
173
174 pa_mainloop_wakeup(e->mainloop);
175
176 e->dead = e->mainloop->io_events_scan_dead = e->mainloop->rebuild_pollfds = 1;
177 }
178
179 static void mainloop_io_set_destroy(pa_io_event *e, void (*callback)(pa_mainloop_api*a, pa_io_event *e, void *userdata)) {
180 assert(e);
181 e->destroy_callback = callback;
182 }
183
184 /* Defer events */
185 static pa_defer_event* mainloop_defer_new(pa_mainloop_api*a, void (*callback) (pa_mainloop_api*a, pa_defer_event *e, void *userdata), void *userdata) {
186 pa_mainloop *m;
187 pa_defer_event *e;
188
189 assert(a && a->userdata && callback);
190 m = a->userdata;
191 assert(a == &m->api);
192
193 e = pa_xmalloc(sizeof(pa_defer_event));
194 e->mainloop = m;
195 e->dead = 0;
196
197 e->enabled = 1;
198 e->callback = callback;
199 e->userdata = userdata;
200 e->destroy_callback = NULL;
201
202 pa_idxset_put(m->defer_events, e, NULL);
203
204 m->deferred_pending++;
205 return e;
206 }
207
208 static void mainloop_defer_enable(pa_defer_event *e, int b) {
209 assert(e);
210
211 if (e->enabled && !b) {
212 assert(e->mainloop->deferred_pending > 0);
213 e->mainloop->deferred_pending--;
214 } else if (!e->enabled && b)
215 e->mainloop->deferred_pending++;
216
217 e->enabled = b;
218 }
219
220 static void mainloop_defer_free(pa_defer_event *e) {
221 assert(e);
222 e->dead = e->mainloop->defer_events_scan_dead = 1;
223
224 if (e->enabled) {
225 e->enabled = 0;
226 assert(e->mainloop->deferred_pending > 0);
227 e->mainloop->deferred_pending--;
228 }
229 }
230
231 static void mainloop_defer_set_destroy(pa_defer_event *e, void (*callback)(pa_mainloop_api*a, pa_defer_event *e, void *userdata)) {
232 assert(e);
233 e->destroy_callback = callback;
234 }
235
236 /* Time events */
237 static pa_time_event* mainloop_time_new(pa_mainloop_api*a, const struct timeval *tv, void (*callback) (pa_mainloop_api*a, pa_time_event*e, const struct timeval *tv, void *userdata), void *userdata) {
238 pa_mainloop *m;
239 pa_time_event *e;
240
241 assert(a && a->userdata && callback);
242 m = a->userdata;
243 assert(a == &m->api);
244
245 pa_mainloop_wakeup(m);
246
247 e = pa_xmalloc(sizeof(pa_time_event));
248 e->mainloop = m;
249 e->dead = 0;
250
251 e->enabled = !!tv;
252 if (tv)
253 e->timeval = *tv;
254
255 e->callback = callback;
256 e->userdata = userdata;
257 e->destroy_callback = NULL;
258
259 pa_idxset_put(m->time_events, e, NULL);
260
261 return e;
262 }
263
264 static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) {
265 assert(e);
266
267 pa_mainloop_wakeup(e->mainloop);
268
269 if (tv) {
270 e->enabled = 1;
271 e->timeval = *tv;
272 } else
273 e->enabled = 0;
274 }
275
276 static void mainloop_time_free(pa_time_event *e) {
277 assert(e);
278
279 pa_mainloop_wakeup(e->mainloop);
280
281 e->dead = e->mainloop->time_events_scan_dead = 1;
282 }
283
284 static void mainloop_time_set_destroy(pa_time_event *e, void (*callback)(pa_mainloop_api*a, pa_time_event *e, void *userdata)) {
285 assert(e);
286 e->destroy_callback = callback;
287 }
288
289 /* quit() */
290
291 static void mainloop_quit(pa_mainloop_api*a, int retval) {
292 pa_mainloop *m;
293 assert(a && a->userdata);
294 m = a->userdata;
295 assert(a == &m->api);
296
297 pa_mainloop_wakeup(m);
298
299 m->quit = 1;
300 m->retval = retval;
301 }
302
303 static const pa_mainloop_api vtable = {
304 .userdata = NULL,
305
306 .io_new= mainloop_io_new,
307 .io_enable= mainloop_io_enable,
308 .io_free= mainloop_io_free,
309 .io_set_destroy= mainloop_io_set_destroy,
310
311 .time_new = mainloop_time_new,
312 .time_restart = mainloop_time_restart,
313 .time_free = mainloop_time_free,
314 .time_set_destroy = mainloop_time_set_destroy,
315
316 .defer_new = mainloop_defer_new,
317 .defer_enable = mainloop_defer_enable,
318 .defer_free = mainloop_defer_free,
319 .defer_set_destroy = mainloop_defer_set_destroy,
320
321 .quit = mainloop_quit,
322 };
323
324 pa_mainloop *pa_mainloop_new(void) {
325 pa_mainloop *m;
326
327 m = pa_xmalloc(sizeof(pa_mainloop));
328
329 #ifndef OS_IS_WIN32
330 if (pipe(m->wakeup_pipe) < 0) {
331 pa_xfree(m);
332 return NULL;
333 }
334
335 pa_make_nonblock_fd(m->wakeup_pipe[0]);
336 pa_make_nonblock_fd(m->wakeup_pipe[1]);
337 #else
338 m->wakeup_pipe[0] = -1;
339 m->wakeup_pipe[1] = -1;
340 #endif
341
342 m->io_events = pa_idxset_new(NULL, NULL);
343 m->defer_events = pa_idxset_new(NULL, NULL);
344 m->time_events = pa_idxset_new(NULL, NULL);
345
346 assert(m->io_events && m->defer_events && m->time_events);
347
348 m->io_events_scan_dead = m->defer_events_scan_dead = m->time_events_scan_dead = 0;
349
350 m->pollfds = NULL;
351 m->max_pollfds = m->n_pollfds = m->rebuild_pollfds = 0;
352
353 m->quit = m->retval = 0;
354
355 m->api = vtable;
356 m->api.userdata = m;
357
358 m->deferred_pending = 0;
359
360 m->state = STATE_PASSIVE;
361
362 m->poll_func = NULL;
363 m->poll_func_userdata = NULL;
364
365 return m;
366 }
367
368 static int io_foreach(void *p, uint32_t PA_GCC_UNUSED idx, int *del, void*userdata) {
369 pa_io_event *e = p;
370 int *all = userdata;
371 assert(e && del && all);
372
373 if (!*all && !e->dead)
374 return 0;
375
376 if (e->destroy_callback)
377 e->destroy_callback(&e->mainloop->api, e, e->userdata);
378 pa_xfree(e);
379 *del = 1;
380 return 0;
381 }
382
383 static int time_foreach(void *p, uint32_t PA_GCC_UNUSED idx, int *del, void*userdata) {
384 pa_time_event *e = p;
385 int *all = userdata;
386 assert(e && del && all);
387
388 if (!*all && !e->dead)
389 return 0;
390
391 if (e->destroy_callback)
392 e->destroy_callback(&e->mainloop->api, e, e->userdata);
393 pa_xfree(e);
394 *del = 1;
395 return 0;
396 }
397
398 static int defer_foreach(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void*userdata) {
399 pa_defer_event *e = p;
400 int *all = userdata;
401 assert(e && del && all);
402
403 if (!*all && !e->dead)
404 return 0;
405
406 if (e->destroy_callback)
407 e->destroy_callback(&e->mainloop->api, e, e->userdata);
408 pa_xfree(e);
409 *del = 1;
410 return 0;
411 }
412
413 void pa_mainloop_free(pa_mainloop* m) {
414 int all = 1;
415 assert(m && (m->state != STATE_POLLING));
416
417 pa_idxset_foreach(m->io_events, io_foreach, &all);
418 pa_idxset_foreach(m->time_events, time_foreach, &all);
419 pa_idxset_foreach(m->defer_events, defer_foreach, &all);
420
421 pa_idxset_free(m->io_events, NULL, NULL);
422 pa_idxset_free(m->time_events, NULL, NULL);
423 pa_idxset_free(m->defer_events, NULL, NULL);
424
425 pa_xfree(m->pollfds);
426
427 if (m->wakeup_pipe[0] >= 0)
428 close(m->wakeup_pipe[0]);
429 if (m->wakeup_pipe[1] >= 0)
430 close(m->wakeup_pipe[1]);
431
432 pa_xfree(m);
433 }
434
435 static void scan_dead(pa_mainloop *m) {
436 int all = 0;
437 assert(m);
438
439 if (m->io_events_scan_dead)
440 pa_idxset_foreach(m->io_events, io_foreach, &all);
441 if (m->time_events_scan_dead)
442 pa_idxset_foreach(m->time_events, time_foreach, &all);
443 if (m->defer_events_scan_dead)
444 pa_idxset_foreach(m->defer_events, defer_foreach, &all);
445
446 m->io_events_scan_dead = m->time_events_scan_dead = m->defer_events_scan_dead = 0;
447 }
448
449 static void rebuild_pollfds(pa_mainloop *m) {
450 pa_io_event*e;
451 struct pollfd *p;
452 uint32_t idx = PA_IDXSET_INVALID;
453 unsigned l;
454
455 l = pa_idxset_size(m->io_events) + 1;
456 if (m->max_pollfds < l) {
457 m->pollfds = pa_xrealloc(m->pollfds, sizeof(struct pollfd)*l);
458 m->max_pollfds = l;
459 }
460
461 m->n_pollfds = 0;
462 p = m->pollfds;
463
464 if (m->wakeup_pipe[0] >= 0) {
465 m->pollfds[0].fd = m->wakeup_pipe[0];
466 m->pollfds[0].events = POLLIN;
467 m->pollfds[0].revents = 0;
468 p++;
469 m->n_pollfds++;
470 }
471
472 for (e = pa_idxset_first(m->io_events, &idx); e; e = pa_idxset_next(m->io_events, &idx)) {
473 if (e->dead) {
474 e->pollfd = NULL;
475 continue;
476 }
477
478 e->pollfd = p;
479 p->fd = e->fd;
480 p->events =
481 ((e->events & PA_IO_EVENT_INPUT) ? POLLIN : 0) |
482 ((e->events & PA_IO_EVENT_OUTPUT) ? POLLOUT : 0) |
483 POLLHUP |
484 POLLERR;
485 p->revents = 0;
486
487 p++;
488 m->n_pollfds++;
489 }
490
491 m->rebuild_pollfds = 0;
492 }
493
494 static int dispatch_pollfds(pa_mainloop *m) {
495 uint32_t idx = PA_IDXSET_INVALID;
496 pa_io_event *e;
497 int r = 0;
498
499 for (e = pa_idxset_first(m->io_events, &idx); e && !m->quit; e = pa_idxset_next(m->io_events, &idx)) {
500 if (e->dead || !e->pollfd || !e->pollfd->revents)
501 continue;
502
503 assert(e->pollfd->fd == e->fd && e->callback);
504 e->callback(&m->api, e, e->fd,
505 (e->pollfd->revents & POLLHUP ? PA_IO_EVENT_HANGUP : 0) |
506 (e->pollfd->revents & POLLIN ? PA_IO_EVENT_INPUT : 0) |
507 (e->pollfd->revents & POLLOUT ? PA_IO_EVENT_OUTPUT : 0) |
508 (e->pollfd->revents & POLLERR ? PA_IO_EVENT_ERROR : 0),
509 e->userdata);
510 e->pollfd->revents = 0;
511 r++;
512 }
513
514 return r;
515 }
516
517 static int dispatch_defer(pa_mainloop *m) {
518 uint32_t idx;
519 pa_defer_event *e;
520 int r = 0;
521
522 if (!m->deferred_pending)
523 return 0;
524
525 for (e = pa_idxset_first(m->defer_events, &idx); e && !m->quit; e = pa_idxset_next(m->defer_events, &idx)) {
526 if (e->dead || !e->enabled)
527 continue;
528
529 assert(e->callback);
530 e->callback(&m->api, e, e->userdata);
531 r++;
532 }
533
534 return r;
535 }
536
537 static int calc_next_timeout(pa_mainloop *m) {
538 uint32_t idx;
539 pa_time_event *e;
540 struct timeval now;
541 int t = -1;
542 int got_time = 0;
543
544 if (pa_idxset_isempty(m->time_events))
545 return -1;
546
547 for (e = pa_idxset_first(m->time_events, &idx); e; e = pa_idxset_next(m->time_events, &idx)) {
548 int tmp;
549
550 if (e->dead || !e->enabled)
551 continue;
552
553 /* Let's save a system call */
554 if (!got_time) {
555 pa_gettimeofday(&now);
556 got_time = 1;
557 }
558
559 if (e->timeval.tv_sec < now.tv_sec || (e->timeval.tv_sec == now.tv_sec && e->timeval.tv_usec <= now.tv_usec))
560 return 0;
561
562 tmp = (e->timeval.tv_sec - now.tv_sec)*1000;
563
564 if (e->timeval.tv_usec > now.tv_usec)
565 tmp += (e->timeval.tv_usec - now.tv_usec)/1000;
566 else
567 tmp -= (now.tv_usec - e->timeval.tv_usec)/1000;
568
569 if (tmp == 0)
570 return 0;
571 else if (t == -1 || tmp < t)
572 t = tmp;
573 }
574
575 return t;
576 }
577
578 static int dispatch_timeout(pa_mainloop *m) {
579 uint32_t idx;
580 pa_time_event *e;
581 struct timeval now;
582 int got_time = 0;
583 int r = 0;
584 assert(m);
585
586 if (pa_idxset_isempty(m->time_events))
587 return 0;
588
589 for (e = pa_idxset_first(m->time_events, &idx); e && !m->quit; e = pa_idxset_next(m->time_events, &idx)) {
590
591 if (e->dead || !e->enabled)
592 continue;
593
594 /* Let's save a system call */
595 if (!got_time) {
596 pa_gettimeofday(&now);
597 got_time = 1;
598 }
599
600 if (e->timeval.tv_sec < now.tv_sec || (e->timeval.tv_sec == now.tv_sec && e->timeval.tv_usec <= now.tv_usec)) {
601 assert(e->callback);
602
603 e->enabled = 0;
604 e->callback(&m->api, e, &e->timeval, e->userdata);
605
606 r++;
607 }
608 }
609
610 return r;
611 }
612
613 void pa_mainloop_wakeup(pa_mainloop *m) {
614 char c = 'W';
615 assert(m);
616
617 if (m->wakeup_pipe[1] >= 0)
618 write(m->wakeup_pipe[1], &c, sizeof(c));
619 }
620
621 static void clear_wakeup(pa_mainloop *m) {
622 char c[10];
623
624 assert(m);
625
626 if (m->wakeup_pipe[0] < 0)
627 return;
628
629 while (read(m->wakeup_pipe[0], &c, sizeof(c)) == sizeof(c));
630 }
631
632 int pa_mainloop_prepare(pa_mainloop *m, int timeout) {
633 assert(m);
634 assert(m->state == STATE_PASSIVE);
635
636 clear_wakeup(m);
637 scan_dead(m);
638
639 if (m->quit)
640 goto quit;
641
642 if (!m->deferred_pending) {
643
644 if (m->rebuild_pollfds)
645 rebuild_pollfds(m);
646
647 m->prepared_timeout = calc_next_timeout(m);
648 if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0))
649 m->prepared_timeout = timeout;
650 }
651
652 m->state = STATE_PREPARED;
653 return 0;
654
655 quit:
656 m->state = STATE_QUIT;
657 return -2;
658 }
659
660 int pa_mainloop_poll(pa_mainloop *m) {
661 int r;
662
663 assert(m);
664 assert(m->state == STATE_PREPARED);
665
666 if (m->quit)
667 goto quit;
668
669 m->state = STATE_POLLING;
670
671 if (m->deferred_pending)
672 r = 0;
673 else {
674 if (m->poll_func)
675 r = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata);
676 else
677 r = poll(m->pollfds, m->n_pollfds, m->prepared_timeout);
678
679 if (r < 0) {
680 if (errno == EINTR)
681 r = 0;
682 else
683 pa_log(__FILE__": poll(): %s", strerror(errno));
684 }
685 }
686
687 m->state = r < 0 ? STATE_PASSIVE : STATE_POLLED;
688 return r;
689
690 quit:
691 m->state = STATE_QUIT;
692 return -2;
693 }
694
695 int pa_mainloop_dispatch(pa_mainloop *m) {
696 int dispatched = 0;
697
698 assert(m);
699 assert(m->state == STATE_POLLED);
700
701 if (m->quit)
702 goto quit;
703
704 if (m->deferred_pending)
705 dispatched += dispatch_defer(m);
706 else {
707 dispatched += dispatch_timeout(m);
708
709 if (m->quit)
710 goto quit;
711
712 dispatched += dispatch_pollfds(m);
713
714 }
715
716 if (m->quit)
717 goto quit;
718
719 m->state = STATE_PASSIVE;
720
721 return dispatched;
722
723 quit:
724 m->state = STATE_QUIT;
725 return -2;
726 }
727
728 int pa_mainloop_get_retval(pa_mainloop *m) {
729 assert(m);
730 return m->retval;
731 }
732
733 int pa_mainloop_iterate(pa_mainloop *m, int block, int *retval) {
734 int r;
735 assert(m);
736
737 if ((r = pa_mainloop_prepare(m, block ? -1 : 0)) < 0)
738 goto quit;
739
740 if ((r = pa_mainloop_poll(m)) < 0)
741 goto quit;
742
743 if ((r = pa_mainloop_dispatch(m)) < 0)
744 goto quit;
745
746 return r;
747
748 quit:
749
750 if ((r == -2) && retval)
751 *retval = pa_mainloop_get_retval(m);
752 return r;
753 }
754
755 int pa_mainloop_run(pa_mainloop *m, int *retval) {
756 int r;
757
758 while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0);
759
760 if (r == -2)
761 return 1;
762 else if (r < 0)
763 return -1;
764 else
765 return 0;
766 }
767
768 void pa_mainloop_quit(pa_mainloop *m, int r) {
769 assert(m);
770 pa_mainloop_wakeup(m);
771 m->quit = r;
772 }
773
774 pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) {
775 assert(m);
776 return &m->api;
777 }
778
779 void pa_mainloop_set_poll_func(pa_mainloop *m, pa_poll_func poll_func, void *userdata) {
780 assert(m);
781
782 m->poll_func = poll_func;
783 m->poll_func_userdata = userdata;
784 }
785
786
787 #if 0
788 void pa_mainloop_dump(pa_mainloop *m) {
789 assert(m);
790
791 pa_log(__FILE__": Dumping mainloop sources START");
792
793 {
794 uint32_t idx = PA_IDXSET_INVALID;
795 pa_io_event *e;
796 for (e = pa_idxset_first(m->io_events, &idx); e; e = pa_idxset_next(m->io_events, &idx)) {
797 if (e->dead)
798 continue;
799
800 pa_log(__FILE__": kind=io fd=%i events=%i callback=%p userdata=%p", e->fd, (int) e->events, (void*) e->callback, (void*) e->userdata);
801 }
802 }
803 {
804 uint32_t idx = PA_IDXSET_INVALID;
805 pa_defer_event *e;
806 for (e = pa_idxset_first(m->defer_events, &idx); e; e = pa_idxset_next(m->defer_events, &idx)) {
807 if (e->dead)
808 continue;
809
810 pa_log(__FILE__": kind=defer enabled=%i callback=%p userdata=%p", e->enabled, (void*) e->callback, (void*) e->userdata);
811 }
812 }
813 {
814 uint32_t idx = PA_IDXSET_INVALID;
815 pa_time_event *e;
816 for (e = pa_idxset_first(m->time_events, &idx); e; e = pa_idxset_next(m->time_events, &idx)) {
817 if (e->dead)
818 continue;
819
820 pa_log(__FILE__": kind=time enabled=%i time=%lu.%lu callback=%p userdata=%p", e->enabled, (unsigned long) e->timeval.tv_sec, (unsigned long) e->timeval.tv_usec, (void*) e->callback, (void*) e->userdata);
821 }
822 }
823
824 pa_log(__FILE__": Dumping mainloop sources STOP");
825
826 }
827 #endif