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
34 #include <pulsecore/pipe.h>
37 #include <pulse/rtclock.h>
38 #include <pulse/timeval.h>
39 #include <pulse/xmalloc.h>
41 #include <pulsecore/poll.h>
42 #include <pulsecore/core-rtclock.h>
43 #include <pulsecore/core-util.h>
44 #include <pulsecore/i18n.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>
55 pa_mainloop
*mainloop
;
59 pa_io_event_flags_t events
;
60 struct pollfd
*pollfd
;
62 pa_io_event_cb_t callback
;
64 pa_io_event_destroy_cb_t destroy_callback
;
66 PA_LLIST_FIELDS(pa_io_event
);
69 struct pa_time_event
{
70 pa_mainloop
*mainloop
;
74 pa_bool_t use_rtclock
:1;
77 pa_time_event_cb_t callback
;
79 pa_time_event_destroy_cb_t destroy_callback
;
81 PA_LLIST_FIELDS(pa_time_event
);
84 struct pa_defer_event
{
85 pa_mainloop
*mainloop
;
90 pa_defer_event_cb_t callback
;
92 pa_defer_event_destroy_cb_t destroy_callback
;
94 PA_LLIST_FIELDS(pa_defer_event
);
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
);
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
;
105 pa_bool_t rebuild_pollfds
:1;
106 struct pollfd
*pollfds
;
107 unsigned max_pollfds
, n_pollfds
;
109 pa_usec_t prepared_timeout
;
110 pa_time_event
*cached_next_time_event
;
117 pa_bool_t wakeup_requested
:1;
119 int wakeup_pipe_type
;
129 pa_poll_func poll_func
;
130 void *poll_func_userdata
;
134 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
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));
142 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
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);
151 static pa_io_event
* mainloop_io_new(
154 pa_io_event_flags_t events
,
155 pa_io_event_cb_t callback
,
162 pa_assert(a
->userdata
);
167 pa_assert(a
== &m
->api
);
169 e
= pa_xnew0(pa_io_event
, 1);
175 e
->callback
= callback
;
176 e
->userdata
= userdata
;
189 if ((select(fd
, NULL
, NULL
, &xset
, &tv
) == -1) && (WSAGetLastError() == WSAENOTSOCK
)) {
190 pa_log_warn("Cannot monitor non-socket file descriptors.");
196 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
197 m
->rebuild_pollfds
= TRUE
;
200 pa_mainloop_wakeup(m
);
205 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
209 if (e
->events
== events
)
215 e
->pollfd
->events
= map_flags_to_libc(events
);
217 e
->mainloop
->rebuild_pollfds
= TRUE
;
219 pa_mainloop_wakeup(e
->mainloop
);
222 static void mainloop_io_free(pa_io_event
*e
) {
227 e
->mainloop
->io_events_please_scan
++;
229 e
->mainloop
->n_io_events
--;
230 e
->mainloop
->rebuild_pollfds
= TRUE
;
232 pa_mainloop_wakeup(e
->mainloop
);
235 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
238 e
->destroy_callback
= callback
;
242 static pa_defer_event
* mainloop_defer_new(
244 pa_defer_event_cb_t callback
,
251 pa_assert(a
->userdata
);
255 pa_assert(a
== &m
->api
);
257 e
= pa_xnew0(pa_defer_event
, 1);
261 m
->n_enabled_defer_events
++;
263 e
->callback
= callback
;
264 e
->userdata
= userdata
;
266 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
268 pa_mainloop_wakeup(e
->mainloop
);
273 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
277 if (e
->enabled
&& !b
) {
278 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
279 e
->mainloop
->n_enabled_defer_events
--;
280 } else if (!e
->enabled
&& b
) {
281 e
->mainloop
->n_enabled_defer_events
++;
282 pa_mainloop_wakeup(e
->mainloop
);
288 static void mainloop_defer_free(pa_defer_event
*e
) {
293 e
->mainloop
->defer_events_please_scan
++;
296 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
297 e
->mainloop
->n_enabled_defer_events
--;
302 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
306 e
->destroy_callback
= callback
;
310 static pa_usec_t
make_rt(const struct timeval
*tv
, pa_bool_t
*use_rtclock
) {
314 *use_rtclock
= FALSE
;
315 return PA_USEC_INVALID
;
319 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
322 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
324 pa_rtclock_from_wallclock(&ttv
);
326 return pa_timeval_load(&ttv
);
329 static pa_time_event
* mainloop_time_new(
331 const struct timeval
*tv
,
332 pa_time_event_cb_t callback
,
338 pa_bool_t use_rtclock
= FALSE
;
341 pa_assert(a
->userdata
);
344 t
= make_rt(tv
, &use_rtclock
);
347 pa_assert(a
== &m
->api
);
349 e
= pa_xnew0(pa_time_event
, 1);
352 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
354 e
->use_rtclock
= use_rtclock
;
356 m
->n_enabled_time_events
++;
358 if (m
->cached_next_time_event
) {
359 pa_assert(m
->cached_next_time_event
->enabled
);
361 if (t
< m
->cached_next_time_event
->time
)
362 m
->cached_next_time_event
= e
;
366 e
->callback
= callback
;
367 e
->userdata
= userdata
;
369 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
372 pa_mainloop_wakeup(m
);
377 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
380 pa_bool_t use_rtclock
= FALSE
;
385 t
= make_rt(tv
, &use_rtclock
);
387 valid
= (t
!= PA_USEC_INVALID
);
388 if (e
->enabled
&& !valid
) {
389 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
390 e
->mainloop
->n_enabled_time_events
--;
391 } else if (!e
->enabled
&& valid
)
392 e
->mainloop
->n_enabled_time_events
++;
394 if ((e
->enabled
= valid
)) {
396 e
->use_rtclock
= use_rtclock
;
397 pa_mainloop_wakeup(e
->mainloop
);
400 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
401 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
403 if (t
< e
->mainloop
->cached_next_time_event
->time
)
404 e
->mainloop
->cached_next_time_event
= e
;
405 } else if (e
->mainloop
->cached_next_time_event
== e
)
406 e
->mainloop
->cached_next_time_event
= NULL
;
409 static void mainloop_time_free(pa_time_event
*e
) {
414 e
->mainloop
->time_events_please_scan
++;
417 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
418 e
->mainloop
->n_enabled_time_events
--;
422 if (e
->mainloop
->cached_next_time_event
== e
)
423 e
->mainloop
->cached_next_time_event
= NULL
;
425 /* no wakeup needed here. Think about it! */
428 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
432 e
->destroy_callback
= callback
;
437 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
441 pa_assert(a
->userdata
);
443 pa_assert(a
== &m
->api
);
445 pa_mainloop_quit(m
, retval
);
448 static const pa_mainloop_api vtable
= {
451 .io_new
= mainloop_io_new
,
452 .io_enable
= mainloop_io_enable
,
453 .io_free
= mainloop_io_free
,
454 .io_set_destroy
= mainloop_io_set_destroy
,
456 .time_new
= mainloop_time_new
,
457 .time_restart
= mainloop_time_restart
,
458 .time_free
= mainloop_time_free
,
459 .time_set_destroy
= mainloop_time_set_destroy
,
461 .defer_new
= mainloop_defer_new
,
462 .defer_enable
= mainloop_defer_enable
,
463 .defer_free
= mainloop_defer_free
,
464 .defer_set_destroy
= mainloop_defer_set_destroy
,
466 .quit
= mainloop_quit
,
469 pa_mainloop
*pa_mainloop_new(void) {
474 m
= pa_xnew0(pa_mainloop
, 1);
476 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
477 pa_log_error("ERROR: cannot create wakeup pipe");
482 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
483 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
485 m
->rebuild_pollfds
= TRUE
;
490 m
->state
= STATE_PASSIVE
;
492 m
->poll_func_ret
= -1;
497 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
500 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
502 if (!force
&& m
->io_events_please_scan
<= 0)
505 if (force
|| e
->dead
) {
506 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
509 pa_assert(m
->io_events_please_scan
> 0);
510 m
->io_events_please_scan
--;
513 if (e
->destroy_callback
)
514 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
518 m
->rebuild_pollfds
= TRUE
;
522 pa_assert(m
->io_events_please_scan
== 0);
525 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
526 pa_time_event
*e
, *n
;
528 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
530 if (!force
&& m
->time_events_please_scan
<= 0)
533 if (force
|| e
->dead
) {
534 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
537 pa_assert(m
->time_events_please_scan
> 0);
538 m
->time_events_please_scan
--;
541 if (!e
->dead
&& e
->enabled
) {
542 pa_assert(m
->n_enabled_time_events
> 0);
543 m
->n_enabled_time_events
--;
547 if (e
->destroy_callback
)
548 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
554 pa_assert(m
->time_events_please_scan
== 0);
557 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
558 pa_defer_event
*e
, *n
;
560 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
562 if (!force
&& m
->defer_events_please_scan
<= 0)
565 if (force
|| e
->dead
) {
566 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
569 pa_assert(m
->defer_events_please_scan
> 0);
570 m
->defer_events_please_scan
--;
573 if (!e
->dead
&& e
->enabled
) {
574 pa_assert(m
->n_enabled_defer_events
> 0);
575 m
->n_enabled_defer_events
--;
579 if (e
->destroy_callback
)
580 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
586 pa_assert(m
->defer_events_please_scan
== 0);
590 void pa_mainloop_free(pa_mainloop
*m
) {
593 cleanup_io_events(m
, TRUE
);
594 cleanup_defer_events(m
, TRUE
);
595 cleanup_time_events(m
, TRUE
);
597 pa_xfree(m
->pollfds
);
599 pa_close_pipe(m
->wakeup_pipe
);
604 static void scan_dead(pa_mainloop
*m
) {
607 if (m
->io_events_please_scan
)
608 cleanup_io_events(m
, FALSE
);
610 if (m
->time_events_please_scan
)
611 cleanup_time_events(m
, FALSE
);
613 if (m
->defer_events_please_scan
)
614 cleanup_defer_events(m
, FALSE
);
617 static void rebuild_pollfds(pa_mainloop
*m
) {
622 l
= m
->n_io_events
+ 1;
623 if (m
->max_pollfds
< l
) {
625 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
632 if (m
->wakeup_pipe
[0] >= 0) {
633 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
634 m
->pollfds
[0].events
= POLLIN
;
635 m
->pollfds
[0].revents
= 0;
640 PA_LLIST_FOREACH(e
, m
->io_events
) {
648 p
->events
= map_flags_to_libc(e
->events
);
655 m
->rebuild_pollfds
= FALSE
;
658 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
662 pa_assert(m
->poll_func_ret
> 0);
664 k
= m
->poll_func_ret
;
666 PA_LLIST_FOREACH(e
, m
->io_events
) {
668 if (k
<= 0 || m
->quit
)
671 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
674 pa_assert(e
->pollfd
->fd
== e
->fd
);
675 pa_assert(e
->callback
);
677 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
678 e
->pollfd
->revents
= 0;
686 static unsigned dispatch_defer(pa_mainloop
*m
) {
690 if (m
->n_enabled_defer_events
<= 0)
693 PA_LLIST_FOREACH(e
, m
->defer_events
) {
698 if (e
->dead
|| !e
->enabled
)
701 pa_assert(e
->callback
);
702 e
->callback(&m
->api
, e
, e
->userdata
);
709 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
710 pa_time_event
*t
, *n
= NULL
;
713 if (m
->cached_next_time_event
)
714 return m
->cached_next_time_event
;
716 PA_LLIST_FOREACH(t
, m
->time_events
) {
718 if (t
->dead
|| !t
->enabled
)
721 if (!n
|| t
->time
< n
->time
) {
724 /* Shortcut for time == 0 */
730 m
->cached_next_time_event
= n
;
734 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
738 if (m
->n_enabled_time_events
<= 0)
739 return PA_USEC_INVALID
;
741 pa_assert_se(t
= find_next_time_event(m
));
746 clock_now
= pa_rtclock_now();
748 if (t
->time
<= clock_now
)
751 return t
->time
- clock_now
;
754 static unsigned dispatch_timeout(pa_mainloop
*m
) {
760 if (m
->n_enabled_time_events
<= 0)
763 now
= pa_rtclock_now();
765 PA_LLIST_FOREACH(e
, m
->time_events
) {
770 if (e
->dead
|| !e
->enabled
)
773 if (e
->time
<= now
) {
775 pa_assert(e
->callback
);
777 /* Disable time event */
778 mainloop_time_restart(e
, NULL
);
780 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
789 void pa_mainloop_wakeup(pa_mainloop
*m
) {
793 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
794 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
795 m
->wakeup_requested
++;
799 static void clear_wakeup(pa_mainloop
*m
) {
804 if (m
->wakeup_pipe
[0] < 0)
807 if (m
->wakeup_requested
) {
808 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
810 m
->wakeup_requested
= 0;
814 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
816 pa_assert(m
->state
== STATE_PASSIVE
);
824 if (m
->n_enabled_defer_events
<= 0) {
826 if (m
->rebuild_pollfds
)
829 m
->prepared_timeout
= calc_next_timeout(m
);
831 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
833 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
834 m
->prepared_timeout
= timeout
;
838 m
->state
= STATE_PREPARED
;
842 m
->state
= STATE_QUIT
;
846 static int usec_to_timeout(pa_usec_t u
) {
849 if (u
== PA_USEC_INVALID
)
852 timeout
= (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
853 pa_assert(timeout
>= 0);
858 int pa_mainloop_poll(pa_mainloop
*m
) {
860 pa_assert(m
->state
== STATE_PREPARED
);
865 m
->state
= STATE_POLLING
;
867 if (m
->n_enabled_defer_events
)
868 m
->poll_func_ret
= 0;
870 pa_assert(!m
->rebuild_pollfds
);
873 m
->poll_func_ret
= m
->poll_func(
874 m
->pollfds
, m
->n_pollfds
,
875 usec_to_timeout(m
->prepared_timeout
),
876 m
->poll_func_userdata
);
881 m
->poll_func_ret
= ppoll(
882 m
->pollfds
, m
->n_pollfds
,
883 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
886 m
->poll_func_ret
= pa_poll(
887 m
->pollfds
, m
->n_pollfds
,
888 usec_to_timeout(m
->prepared_timeout
));
892 if (m
->poll_func_ret
< 0) {
894 m
->poll_func_ret
= 0;
896 pa_log("poll(): %s", pa_cstrerror(errno
));
900 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
901 return m
->poll_func_ret
;
904 m
->state
= STATE_QUIT
;
908 int pa_mainloop_dispatch(pa_mainloop
*m
) {
909 unsigned dispatched
= 0;
912 pa_assert(m
->state
== STATE_POLLED
);
917 if (m
->n_enabled_defer_events
)
918 dispatched
+= dispatch_defer(m
);
920 if (m
->n_enabled_time_events
)
921 dispatched
+= dispatch_timeout(m
);
926 if (m
->poll_func_ret
> 0)
927 dispatched
+= dispatch_pollfds(m
);
933 m
->state
= STATE_PASSIVE
;
935 return (int) dispatched
;
938 m
->state
= STATE_QUIT
;
942 int pa_mainloop_get_retval(pa_mainloop
*m
) {
948 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
952 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
955 if ((r
= pa_mainloop_poll(m
)) < 0)
958 if ((r
= pa_mainloop_dispatch(m
)) < 0)
965 if ((r
== -2) && retval
)
966 *retval
= pa_mainloop_get_retval(m
);
970 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
973 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
984 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
989 pa_mainloop_wakeup(m
);
992 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
998 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
1001 m
->poll_func
= poll_func
;
1002 m
->poll_func_userdata
= userdata
;
1005 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1008 return m
->io_new
== mainloop_io_new
;