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
36 #include <pulsecore/pipe.h>
39 #include <pulse/i18n.h>
40 #include <pulse/rtclock.h>
41 #include <pulse/timeval.h>
42 #include <pulse/xmalloc.h>
44 #include <pulsecore/poll.h>
45 #include <pulsecore/core-rtclock.h>
46 #include <pulsecore/core-util.h>
47 #include <pulsecore/llist.h>
48 #include <pulsecore/log.h>
49 #include <pulsecore/core-error.h>
50 #include <pulsecore/socket.h>
51 #include <pulsecore/macro.h>
57 pa_mainloop
*mainloop
;
61 pa_io_event_flags_t events
;
62 struct pollfd
*pollfd
;
64 pa_io_event_cb_t callback
;
66 pa_io_event_destroy_cb_t destroy_callback
;
68 PA_LLIST_FIELDS(pa_io_event
);
71 struct pa_time_event
{
72 pa_mainloop
*mainloop
;
76 pa_bool_t use_rtclock
:1;
79 pa_time_event_cb_t callback
;
81 pa_time_event_destroy_cb_t destroy_callback
;
83 PA_LLIST_FIELDS(pa_time_event
);
86 struct pa_defer_event
{
87 pa_mainloop
*mainloop
;
92 pa_defer_event_cb_t callback
;
94 pa_defer_event_destroy_cb_t destroy_callback
;
96 PA_LLIST_FIELDS(pa_defer_event
);
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
);
104 unsigned n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
105 unsigned io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
107 pa_bool_t rebuild_pollfds
:1;
108 struct pollfd
*pollfds
;
109 unsigned max_pollfds
, n_pollfds
;
111 pa_usec_t prepared_timeout
;
112 pa_time_event
*cached_next_time_event
;
119 pa_bool_t wakeup_requested
:1;
121 int wakeup_pipe_type
;
131 pa_poll_func poll_func
;
132 void *poll_func_userdata
;
136 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
138 ((flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
139 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
140 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
141 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0));
144 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
146 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
147 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
148 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
149 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
153 static pa_io_event
* mainloop_io_new(
156 pa_io_event_flags_t events
,
157 pa_io_event_cb_t callback
,
164 pa_assert(a
->userdata
);
169 pa_assert(a
== &m
->api
);
171 e
= pa_xnew0(pa_io_event
, 1);
177 e
->callback
= callback
;
178 e
->userdata
= userdata
;
191 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
192 SELECT_TYPE_ARG5
&tv
) == -1) &&
193 (WSAGetLastError() == WSAENOTSOCK
)) {
194 pa_log_warn("Cannot monitor non-socket file descriptors.");
200 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
201 m
->rebuild_pollfds
= TRUE
;
204 pa_mainloop_wakeup(m
);
209 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
213 if (e
->events
== events
)
219 e
->pollfd
->events
= map_flags_to_libc(events
);
221 e
->mainloop
->rebuild_pollfds
= TRUE
;
223 pa_mainloop_wakeup(e
->mainloop
);
226 static void mainloop_io_free(pa_io_event
*e
) {
231 e
->mainloop
->io_events_please_scan
++;
233 e
->mainloop
->n_io_events
--;
234 e
->mainloop
->rebuild_pollfds
= TRUE
;
236 pa_mainloop_wakeup(e
->mainloop
);
239 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
242 e
->destroy_callback
= callback
;
246 static pa_defer_event
* mainloop_defer_new(
248 pa_defer_event_cb_t callback
,
255 pa_assert(a
->userdata
);
259 pa_assert(a
== &m
->api
);
261 e
= pa_xnew0(pa_defer_event
, 1);
265 m
->n_enabled_defer_events
++;
267 e
->callback
= callback
;
268 e
->userdata
= userdata
;
270 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
272 pa_mainloop_wakeup(e
->mainloop
);
277 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
281 if (e
->enabled
&& !b
) {
282 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
283 e
->mainloop
->n_enabled_defer_events
--;
284 } else if (!e
->enabled
&& b
) {
285 e
->mainloop
->n_enabled_defer_events
++;
286 pa_mainloop_wakeup(e
->mainloop
);
292 static void mainloop_defer_free(pa_defer_event
*e
) {
297 e
->mainloop
->defer_events_please_scan
++;
300 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
301 e
->mainloop
->n_enabled_defer_events
--;
306 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
310 e
->destroy_callback
= callback
;
314 static pa_usec_t
make_rt(const struct timeval
*tv
, pa_bool_t
*use_rtclock
) {
318 *use_rtclock
= FALSE
;
319 return PA_USEC_INVALID
;
323 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
326 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
328 pa_rtclock_from_wallclock(&ttv
);
330 return pa_timeval_load(&ttv
);
333 static pa_time_event
* mainloop_time_new(
335 const struct timeval
*tv
,
336 pa_time_event_cb_t callback
,
342 pa_bool_t use_rtclock
= FALSE
;
345 pa_assert(a
->userdata
);
348 t
= make_rt(tv
, &use_rtclock
);
351 pa_assert(a
== &m
->api
);
353 e
= pa_xnew0(pa_time_event
, 1);
356 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
358 e
->use_rtclock
= use_rtclock
;
360 m
->n_enabled_time_events
++;
362 if (m
->cached_next_time_event
) {
363 pa_assert(m
->cached_next_time_event
->enabled
);
365 if (t
< m
->cached_next_time_event
->time
)
366 m
->cached_next_time_event
= e
;
370 e
->callback
= callback
;
371 e
->userdata
= userdata
;
373 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
376 pa_mainloop_wakeup(m
);
381 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
384 pa_bool_t use_rtclock
= FALSE
;
389 t
= make_rt(tv
, &use_rtclock
);
391 valid
= (t
!= PA_USEC_INVALID
);
392 if (e
->enabled
&& !valid
) {
393 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
394 e
->mainloop
->n_enabled_time_events
--;
395 } else if (!e
->enabled
&& valid
)
396 e
->mainloop
->n_enabled_time_events
++;
398 if ((e
->enabled
= valid
)) {
400 e
->use_rtclock
= use_rtclock
;
401 pa_mainloop_wakeup(e
->mainloop
);
404 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
405 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
407 if (t
< e
->mainloop
->cached_next_time_event
->time
)
408 e
->mainloop
->cached_next_time_event
= e
;
409 } else if (e
->mainloop
->cached_next_time_event
== e
)
410 e
->mainloop
->cached_next_time_event
= NULL
;
413 static void mainloop_time_free(pa_time_event
*e
) {
418 e
->mainloop
->time_events_please_scan
++;
421 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
422 e
->mainloop
->n_enabled_time_events
--;
426 if (e
->mainloop
->cached_next_time_event
== e
)
427 e
->mainloop
->cached_next_time_event
= NULL
;
429 /* no wakeup needed here. Think about it! */
432 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
436 e
->destroy_callback
= callback
;
441 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
445 pa_assert(a
->userdata
);
447 pa_assert(a
== &m
->api
);
449 pa_mainloop_quit(m
, retval
);
452 static const pa_mainloop_api vtable
= {
455 .io_new
= mainloop_io_new
,
456 .io_enable
= mainloop_io_enable
,
457 .io_free
= mainloop_io_free
,
458 .io_set_destroy
= mainloop_io_set_destroy
,
460 .time_new
= mainloop_time_new
,
461 .time_restart
= mainloop_time_restart
,
462 .time_free
= mainloop_time_free
,
463 .time_set_destroy
= mainloop_time_set_destroy
,
465 .defer_new
= mainloop_defer_new
,
466 .defer_enable
= mainloop_defer_enable
,
467 .defer_free
= mainloop_defer_free
,
468 .defer_set_destroy
= mainloop_defer_set_destroy
,
470 .quit
= mainloop_quit
,
473 pa_mainloop
*pa_mainloop_new(void) {
478 m
= pa_xnew0(pa_mainloop
, 1);
480 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
481 pa_log_error("ERROR: cannot create wakeup pipe");
486 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
487 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
489 m
->rebuild_pollfds
= TRUE
;
494 m
->state
= STATE_PASSIVE
;
496 m
->poll_func_ret
= -1;
501 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
504 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
506 if (!force
&& m
->io_events_please_scan
<= 0)
509 if (force
|| e
->dead
) {
510 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
513 pa_assert(m
->io_events_please_scan
> 0);
514 m
->io_events_please_scan
--;
517 if (e
->destroy_callback
)
518 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
522 m
->rebuild_pollfds
= TRUE
;
526 pa_assert(m
->io_events_please_scan
== 0);
529 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
530 pa_time_event
*e
, *n
;
532 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
534 if (!force
&& m
->time_events_please_scan
<= 0)
537 if (force
|| e
->dead
) {
538 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
541 pa_assert(m
->time_events_please_scan
> 0);
542 m
->time_events_please_scan
--;
545 if (!e
->dead
&& e
->enabled
) {
546 pa_assert(m
->n_enabled_time_events
> 0);
547 m
->n_enabled_time_events
--;
551 if (e
->destroy_callback
)
552 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
558 pa_assert(m
->time_events_please_scan
== 0);
561 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
562 pa_defer_event
*e
, *n
;
564 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
566 if (!force
&& m
->defer_events_please_scan
<= 0)
569 if (force
|| e
->dead
) {
570 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
573 pa_assert(m
->defer_events_please_scan
> 0);
574 m
->defer_events_please_scan
--;
577 if (!e
->dead
&& e
->enabled
) {
578 pa_assert(m
->n_enabled_defer_events
> 0);
579 m
->n_enabled_defer_events
--;
583 if (e
->destroy_callback
)
584 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
590 pa_assert(m
->defer_events_please_scan
== 0);
594 void pa_mainloop_free(pa_mainloop
* m
) {
597 cleanup_io_events(m
, TRUE
);
598 cleanup_defer_events(m
, TRUE
);
599 cleanup_time_events(m
, TRUE
);
601 pa_xfree(m
->pollfds
);
603 pa_close_pipe(m
->wakeup_pipe
);
608 static void scan_dead(pa_mainloop
*m
) {
611 if (m
->io_events_please_scan
)
612 cleanup_io_events(m
, FALSE
);
614 if (m
->time_events_please_scan
)
615 cleanup_time_events(m
, FALSE
);
617 if (m
->defer_events_please_scan
)
618 cleanup_defer_events(m
, FALSE
);
621 static void rebuild_pollfds(pa_mainloop
*m
) {
626 l
= m
->n_io_events
+ 1;
627 if (m
->max_pollfds
< l
) {
629 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
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;
644 PA_LLIST_FOREACH(e
, m
->io_events
) {
652 p
->events
= map_flags_to_libc(e
->events
);
659 m
->rebuild_pollfds
= FALSE
;
662 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
666 pa_assert(m
->poll_func_ret
> 0);
668 k
= m
->poll_func_ret
;
670 PA_LLIST_FOREACH(e
, m
->io_events
) {
672 if (k
<= 0 || m
->quit
)
675 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
678 pa_assert(e
->pollfd
->fd
== e
->fd
);
679 pa_assert(e
->callback
);
681 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
682 e
->pollfd
->revents
= 0;
690 static unsigned dispatch_defer(pa_mainloop
*m
) {
694 if (m
->n_enabled_defer_events
<= 0)
697 PA_LLIST_FOREACH(e
, m
->defer_events
) {
702 if (e
->dead
|| !e
->enabled
)
705 pa_assert(e
->callback
);
706 e
->callback(&m
->api
, e
, e
->userdata
);
713 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
714 pa_time_event
*t
, *n
= NULL
;
717 if (m
->cached_next_time_event
)
718 return m
->cached_next_time_event
;
720 PA_LLIST_FOREACH(t
, m
->time_events
) {
722 if (t
->dead
|| !t
->enabled
)
725 if (!n
|| t
->time
< n
->time
) {
728 /* Shortcut for time == 0 */
734 m
->cached_next_time_event
= n
;
738 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
742 if (m
->n_enabled_time_events
<= 0)
743 return PA_USEC_INVALID
;
745 pa_assert_se(t
= find_next_time_event(m
));
750 clock_now
= pa_rtclock_now();
752 if (t
->time
<= clock_now
)
755 return t
->time
- clock_now
;
758 static unsigned dispatch_timeout(pa_mainloop
*m
) {
764 if (m
->n_enabled_time_events
<= 0)
767 now
= pa_rtclock_now();
769 PA_LLIST_FOREACH(e
, m
->time_events
) {
774 if (e
->dead
|| !e
->enabled
)
777 if (e
->time
<= now
) {
779 pa_assert(e
->callback
);
781 /* Disable time event */
782 mainloop_time_restart(e
, NULL
);
784 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
793 void pa_mainloop_wakeup(pa_mainloop
*m
) {
797 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
798 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
799 m
->wakeup_requested
++;
803 static void clear_wakeup(pa_mainloop
*m
) {
808 if (m
->wakeup_pipe
[0] < 0)
811 if (m
->wakeup_requested
) {
812 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
814 m
->wakeup_requested
= 0;
818 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
820 pa_assert(m
->state
== STATE_PASSIVE
);
828 if (m
->n_enabled_defer_events
<= 0) {
830 if (m
->rebuild_pollfds
)
833 m
->prepared_timeout
= calc_next_timeout(m
);
835 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
837 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
838 m
->prepared_timeout
= timeout
;
842 m
->state
= STATE_PREPARED
;
846 m
->state
= STATE_QUIT
;
850 static int usec_to_timeout(pa_usec_t u
) {
851 if (u
== PA_USEC_INVALID
)
854 return (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
857 int pa_mainloop_poll(pa_mainloop
*m
) {
859 pa_assert(m
->state
== STATE_PREPARED
);
864 m
->state
= STATE_POLLING
;
866 if (m
->n_enabled_defer_events
)
867 m
->poll_func_ret
= 0;
869 pa_assert(!m
->rebuild_pollfds
);
872 m
->poll_func_ret
= m
->poll_func(
873 m
->pollfds
, m
->n_pollfds
,
874 usec_to_timeout(m
->prepared_timeout
),
875 m
->poll_func_userdata
);
880 m
->poll_func_ret
= ppoll(
881 m
->pollfds
, m
->n_pollfds
,
882 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
885 m
->poll_func_ret
= pa_poll(
886 m
->pollfds
, m
->n_pollfds
,
887 usec_to_timeout(m
->prepared_timeout
));
891 if (m
->poll_func_ret
< 0) {
893 m
->poll_func_ret
= 0;
895 pa_log("poll(): %s", pa_cstrerror(errno
));
899 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
900 return m
->poll_func_ret
;
903 m
->state
= STATE_QUIT
;
907 int pa_mainloop_dispatch(pa_mainloop
*m
) {
908 unsigned dispatched
= 0;
911 pa_assert(m
->state
== STATE_POLLED
);
916 if (m
->n_enabled_defer_events
)
917 dispatched
+= dispatch_defer(m
);
919 if (m
->n_enabled_time_events
)
920 dispatched
+= dispatch_timeout(m
);
925 if (m
->poll_func_ret
> 0)
926 dispatched
+= dispatch_pollfds(m
);
932 m
->state
= STATE_PASSIVE
;
934 return (int) dispatched
;
937 m
->state
= STATE_QUIT
;
941 int pa_mainloop_get_retval(pa_mainloop
*m
) {
947 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
951 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
954 if ((r
= pa_mainloop_poll(m
)) < 0)
957 if ((r
= pa_mainloop_dispatch(m
)) < 0)
964 if ((r
== -2) && retval
)
965 *retval
= pa_mainloop_get_retval(m
);
969 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
972 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
983 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
988 pa_mainloop_wakeup(m
);
991 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
997 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
1000 m
->poll_func
= poll_func
;
1001 m
->poll_func_userdata
= userdata
;
1004 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1007 return m
->io_new
== mainloop_io_new
;