2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
5 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
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.
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.
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
38 #include <pulsecore/poll.h>
42 #include <pulsecore/pipe.h>
45 #include <pulse/i18n.h>
46 #include <pulse/rtclock.h>
47 #include <pulse/timeval.h>
48 #include <pulse/xmalloc.h>
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>
62 pa_mainloop
*mainloop
;
66 pa_io_event_flags_t events
;
67 struct pollfd
*pollfd
;
69 pa_io_event_cb_t callback
;
71 pa_io_event_destroy_cb_t destroy_callback
;
73 PA_LLIST_FIELDS(pa_io_event
);
76 struct pa_time_event
{
77 pa_mainloop
*mainloop
;
81 pa_bool_t use_rtclock
:1;
84 pa_time_event_cb_t callback
;
86 pa_time_event_destroy_cb_t destroy_callback
;
88 PA_LLIST_FIELDS(pa_time_event
);
91 struct pa_defer_event
{
92 pa_mainloop
*mainloop
;
97 pa_defer_event_cb_t callback
;
99 pa_defer_event_destroy_cb_t destroy_callback
;
101 PA_LLIST_FIELDS(pa_defer_event
);
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
);
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
;
112 pa_bool_t rebuild_pollfds
:1;
113 struct pollfd
*pollfds
;
114 unsigned max_pollfds
, n_pollfds
;
116 pa_usec_t prepared_timeout
;
117 pa_time_event
*cached_next_time_event
;
124 pa_bool_t wakeup_requested
:1;
126 int wakeup_pipe_type
;
136 pa_poll_func poll_func
;
137 void *poll_func_userdata
;
141 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
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));
149 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
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);
158 static pa_io_event
* mainloop_io_new(
161 pa_io_event_flags_t events
,
162 pa_io_event_cb_t callback
,
169 pa_assert(a
->userdata
);
174 pa_assert(a
== &m
->api
);
176 e
= pa_xnew0(pa_io_event
, 1);
182 e
->callback
= callback
;
183 e
->userdata
= userdata
;
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.");
205 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
206 m
->rebuild_pollfds
= TRUE
;
209 pa_mainloop_wakeup(m
);
214 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
218 if (e
->events
== events
)
224 e
->pollfd
->events
= map_flags_to_libc(events
);
226 e
->mainloop
->rebuild_pollfds
= TRUE
;
228 pa_mainloop_wakeup(e
->mainloop
);
231 static void mainloop_io_free(pa_io_event
*e
) {
236 e
->mainloop
->io_events_please_scan
++;
238 e
->mainloop
->n_io_events
--;
239 e
->mainloop
->rebuild_pollfds
= TRUE
;
241 pa_mainloop_wakeup(e
->mainloop
);
244 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
247 e
->destroy_callback
= callback
;
251 static pa_defer_event
* mainloop_defer_new(
253 pa_defer_event_cb_t callback
,
260 pa_assert(a
->userdata
);
264 pa_assert(a
== &m
->api
);
266 e
= pa_xnew0(pa_defer_event
, 1);
270 m
->n_enabled_defer_events
++;
272 e
->callback
= callback
;
273 e
->userdata
= userdata
;
275 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
277 pa_mainloop_wakeup(e
->mainloop
);
282 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
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
);
297 static void mainloop_defer_free(pa_defer_event
*e
) {
302 e
->mainloop
->defer_events_please_scan
++;
305 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
306 e
->mainloop
->n_enabled_defer_events
--;
311 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
315 e
->destroy_callback
= callback
;
319 static pa_usec_t
make_rt(const struct timeval
*tv
, pa_bool_t
*use_rtclock
) {
323 *use_rtclock
= FALSE
;
324 return PA_USEC_INVALID
;
328 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
331 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
333 pa_rtclock_from_wallclock(&ttv
);
335 return pa_timeval_load(&ttv
);
338 static pa_time_event
* mainloop_time_new(
340 const struct timeval
*tv
,
341 pa_time_event_cb_t callback
,
347 pa_bool_t use_rtclock
= FALSE
;
350 pa_assert(a
->userdata
);
353 t
= make_rt(tv
, &use_rtclock
);
356 pa_assert(a
== &m
->api
);
358 e
= pa_xnew0(pa_time_event
, 1);
361 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
363 e
->use_rtclock
= use_rtclock
;
365 m
->n_enabled_time_events
++;
367 if (m
->cached_next_time_event
) {
368 pa_assert(m
->cached_next_time_event
->enabled
);
370 if (t
< m
->cached_next_time_event
->time
)
371 m
->cached_next_time_event
= e
;
375 e
->callback
= callback
;
376 e
->userdata
= userdata
;
378 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
381 pa_mainloop_wakeup(m
);
386 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
389 pa_bool_t use_rtclock
= FALSE
;
394 t
= make_rt(tv
, &use_rtclock
);
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
++;
403 if ((e
->enabled
= valid
)) {
405 e
->use_rtclock
= use_rtclock
;
406 pa_mainloop_wakeup(e
->mainloop
);
409 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
410 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
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
;
418 static void mainloop_time_free(pa_time_event
*e
) {
423 e
->mainloop
->time_events_please_scan
++;
426 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
427 e
->mainloop
->n_enabled_time_events
--;
431 if (e
->mainloop
->cached_next_time_event
== e
)
432 e
->mainloop
->cached_next_time_event
= NULL
;
434 /* no wakeup needed here. Think about it! */
437 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
441 e
->destroy_callback
= callback
;
446 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
450 pa_assert(a
->userdata
);
452 pa_assert(a
== &m
->api
);
454 pa_mainloop_quit(m
, retval
);
457 static const pa_mainloop_api vtable
= {
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
,
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
,
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
,
475 .quit
= mainloop_quit
,
478 pa_mainloop
*pa_mainloop_new(void) {
483 m
= pa_xnew0(pa_mainloop
, 1);
485 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
486 pa_log_error("ERROR: cannot create wakeup pipe");
491 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
492 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
494 m
->rebuild_pollfds
= TRUE
;
499 m
->state
= STATE_PASSIVE
;
501 m
->poll_func_ret
= -1;
506 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
509 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
511 if (!force
&& m
->io_events_please_scan
<= 0)
514 if (force
|| e
->dead
) {
515 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
518 pa_assert(m
->io_events_please_scan
> 0);
519 m
->io_events_please_scan
--;
522 if (e
->destroy_callback
)
523 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
527 m
->rebuild_pollfds
= TRUE
;
531 pa_assert(m
->io_events_please_scan
== 0);
534 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
535 pa_time_event
*e
, *n
;
537 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
539 if (!force
&& m
->time_events_please_scan
<= 0)
542 if (force
|| e
->dead
) {
543 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
546 pa_assert(m
->time_events_please_scan
> 0);
547 m
->time_events_please_scan
--;
550 if (!e
->dead
&& e
->enabled
) {
551 pa_assert(m
->n_enabled_time_events
> 0);
552 m
->n_enabled_time_events
--;
556 if (e
->destroy_callback
)
557 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
563 pa_assert(m
->time_events_please_scan
== 0);
566 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
567 pa_defer_event
*e
, *n
;
569 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
571 if (!force
&& m
->defer_events_please_scan
<= 0)
574 if (force
|| e
->dead
) {
575 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
578 pa_assert(m
->defer_events_please_scan
> 0);
579 m
->defer_events_please_scan
--;
582 if (!e
->dead
&& e
->enabled
) {
583 pa_assert(m
->n_enabled_defer_events
> 0);
584 m
->n_enabled_defer_events
--;
588 if (e
->destroy_callback
)
589 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
595 pa_assert(m
->defer_events_please_scan
== 0);
599 void pa_mainloop_free(pa_mainloop
* m
) {
602 cleanup_io_events(m
, TRUE
);
603 cleanup_defer_events(m
, TRUE
);
604 cleanup_time_events(m
, TRUE
);
606 pa_xfree(m
->pollfds
);
608 pa_close_pipe(m
->wakeup_pipe
);
613 static void scan_dead(pa_mainloop
*m
) {
616 if (m
->io_events_please_scan
)
617 cleanup_io_events(m
, FALSE
);
619 if (m
->time_events_please_scan
)
620 cleanup_time_events(m
, FALSE
);
622 if (m
->defer_events_please_scan
)
623 cleanup_defer_events(m
, FALSE
);
626 static void rebuild_pollfds(pa_mainloop
*m
) {
631 l
= m
->n_io_events
+ 1;
632 if (m
->max_pollfds
< l
) {
634 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
641 if (m
->wakeup_pipe
[0] >= 0) {
642 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
643 m
->pollfds
[0].events
= POLLIN
;
644 m
->pollfds
[0].revents
= 0;
649 PA_LLIST_FOREACH(e
, m
->io_events
) {
657 p
->events
= map_flags_to_libc(e
->events
);
664 m
->rebuild_pollfds
= FALSE
;
667 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
671 pa_assert(m
->poll_func_ret
> 0);
673 k
= m
->poll_func_ret
;
675 PA_LLIST_FOREACH(e
, m
->io_events
) {
677 if (k
<= 0 || m
->quit
)
680 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
683 pa_assert(e
->pollfd
->fd
== e
->fd
);
684 pa_assert(e
->callback
);
686 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
687 e
->pollfd
->revents
= 0;
695 static unsigned dispatch_defer(pa_mainloop
*m
) {
699 if (m
->n_enabled_defer_events
<= 0)
702 PA_LLIST_FOREACH(e
, m
->defer_events
) {
707 if (e
->dead
|| !e
->enabled
)
710 pa_assert(e
->callback
);
711 e
->callback(&m
->api
, e
, e
->userdata
);
718 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
719 pa_time_event
*t
, *n
= NULL
;
722 if (m
->cached_next_time_event
)
723 return m
->cached_next_time_event
;
725 PA_LLIST_FOREACH(t
, m
->time_events
) {
727 if (t
->dead
|| !t
->enabled
)
730 if (!n
|| t
->time
< n
->time
) {
733 /* Shortcut for time == 0 */
739 m
->cached_next_time_event
= n
;
743 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
747 if (m
->n_enabled_time_events
<= 0)
748 return PA_USEC_INVALID
;
750 pa_assert_se(t
= find_next_time_event(m
));
755 clock_now
= pa_rtclock_now();
757 if (t
->time
<= clock_now
)
760 return t
->time
- clock_now
;
763 static unsigned dispatch_timeout(pa_mainloop
*m
) {
769 if (m
->n_enabled_time_events
<= 0)
772 now
= pa_rtclock_now();
774 PA_LLIST_FOREACH(e
, m
->time_events
) {
779 if (e
->dead
|| !e
->enabled
)
782 if (e
->time
<= now
) {
784 pa_assert(e
->callback
);
786 /* Disable time event */
787 mainloop_time_restart(e
, NULL
);
789 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
798 void pa_mainloop_wakeup(pa_mainloop
*m
) {
802 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
803 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
804 m
->wakeup_requested
++;
808 static void clear_wakeup(pa_mainloop
*m
) {
813 if (m
->wakeup_pipe
[0] < 0)
816 if (m
->wakeup_requested
) {
817 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
819 m
->wakeup_requested
= 0;
823 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
825 pa_assert(m
->state
== STATE_PASSIVE
);
833 if (m
->n_enabled_defer_events
<= 0) {
835 if (m
->rebuild_pollfds
)
838 m
->prepared_timeout
= calc_next_timeout(m
);
840 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
842 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
843 m
->prepared_timeout
= timeout
;
847 m
->state
= STATE_PREPARED
;
851 m
->state
= STATE_QUIT
;
855 static int usec_to_timeout(pa_usec_t u
) {
856 if (u
== PA_USEC_INVALID
)
859 return (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
862 int pa_mainloop_poll(pa_mainloop
*m
) {
864 pa_assert(m
->state
== STATE_PREPARED
);
869 m
->state
= STATE_POLLING
;
871 if (m
->n_enabled_defer_events
)
872 m
->poll_func_ret
= 0;
874 pa_assert(!m
->rebuild_pollfds
);
877 m
->poll_func_ret
= m
->poll_func(
878 m
->pollfds
, m
->n_pollfds
,
879 usec_to_timeout(m
->prepared_timeout
),
880 m
->poll_func_userdata
);
885 m
->poll_func_ret
= ppoll(
886 m
->pollfds
, m
->n_pollfds
,
887 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
890 m
->poll_func_ret
= poll(
891 m
->pollfds
, m
->n_pollfds
,
892 usec_to_timeout(m
->prepared_timeout
));
896 if (m
->poll_func_ret
< 0) {
898 m
->poll_func_ret
= 0;
900 pa_log("poll(): %s", pa_cstrerror(errno
));
904 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
905 return m
->poll_func_ret
;
908 m
->state
= STATE_QUIT
;
912 int pa_mainloop_dispatch(pa_mainloop
*m
) {
913 unsigned dispatched
= 0;
916 pa_assert(m
->state
== STATE_POLLED
);
921 if (m
->n_enabled_defer_events
)
922 dispatched
+= dispatch_defer(m
);
924 if (m
->n_enabled_time_events
)
925 dispatched
+= dispatch_timeout(m
);
930 if (m
->poll_func_ret
> 0)
931 dispatched
+= dispatch_pollfds(m
);
937 m
->state
= STATE_PASSIVE
;
939 return (int) dispatched
;
942 m
->state
= STATE_QUIT
;
946 int pa_mainloop_get_retval(pa_mainloop
*m
) {
952 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
956 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
959 if ((r
= pa_mainloop_poll(m
)) < 0)
962 if ((r
= pa_mainloop_dispatch(m
)) < 0)
969 if ((r
== -2) && retval
)
970 *retval
= pa_mainloop_get_retval(m
);
974 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
977 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
988 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
993 pa_mainloop_wakeup(m
);
996 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
1002 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
1005 m
->poll_func
= poll_func
;
1006 m
->poll_func_userdata
= userdata
;
1009 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1012 return m
->io_new
== mainloop_io_new
;