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
;
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 bool 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_atomic_t wakeup_requested
;
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
;
178 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
179 m
->rebuild_pollfds
= true;
182 pa_mainloop_wakeup(m
);
187 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
191 if (e
->events
== events
)
197 e
->pollfd
->events
= map_flags_to_libc(events
);
199 e
->mainloop
->rebuild_pollfds
= true;
201 pa_mainloop_wakeup(e
->mainloop
);
204 static void mainloop_io_free(pa_io_event
*e
) {
209 e
->mainloop
->io_events_please_scan
++;
211 e
->mainloop
->n_io_events
--;
212 e
->mainloop
->rebuild_pollfds
= true;
214 pa_mainloop_wakeup(e
->mainloop
);
217 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
220 e
->destroy_callback
= callback
;
224 static pa_defer_event
* mainloop_defer_new(
226 pa_defer_event_cb_t callback
,
233 pa_assert(a
->userdata
);
237 pa_assert(a
== &m
->api
);
239 e
= pa_xnew0(pa_defer_event
, 1);
243 m
->n_enabled_defer_events
++;
245 e
->callback
= callback
;
246 e
->userdata
= userdata
;
248 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
250 pa_mainloop_wakeup(e
->mainloop
);
255 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
259 if (e
->enabled
&& !b
) {
260 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
261 e
->mainloop
->n_enabled_defer_events
--;
262 } else if (!e
->enabled
&& b
) {
263 e
->mainloop
->n_enabled_defer_events
++;
264 pa_mainloop_wakeup(e
->mainloop
);
270 static void mainloop_defer_free(pa_defer_event
*e
) {
275 e
->mainloop
->defer_events_please_scan
++;
278 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
279 e
->mainloop
->n_enabled_defer_events
--;
284 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
288 e
->destroy_callback
= callback
;
292 static pa_usec_t
make_rt(const struct timeval
*tv
, bool *use_rtclock
) {
296 *use_rtclock
= false;
297 return PA_USEC_INVALID
;
301 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
304 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
306 pa_rtclock_from_wallclock(&ttv
);
308 return pa_timeval_load(&ttv
);
311 static pa_time_event
* mainloop_time_new(
313 const struct timeval
*tv
,
314 pa_time_event_cb_t callback
,
320 bool use_rtclock
= false;
323 pa_assert(a
->userdata
);
326 t
= make_rt(tv
, &use_rtclock
);
329 pa_assert(a
== &m
->api
);
331 e
= pa_xnew0(pa_time_event
, 1);
334 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
336 e
->use_rtclock
= use_rtclock
;
338 m
->n_enabled_time_events
++;
340 if (m
->cached_next_time_event
) {
341 pa_assert(m
->cached_next_time_event
->enabled
);
343 if (t
< m
->cached_next_time_event
->time
)
344 m
->cached_next_time_event
= e
;
348 e
->callback
= callback
;
349 e
->userdata
= userdata
;
351 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
354 pa_mainloop_wakeup(m
);
359 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
362 bool use_rtclock
= false;
367 t
= make_rt(tv
, &use_rtclock
);
369 valid
= (t
!= PA_USEC_INVALID
);
370 if (e
->enabled
&& !valid
) {
371 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
372 e
->mainloop
->n_enabled_time_events
--;
373 } else if (!e
->enabled
&& valid
)
374 e
->mainloop
->n_enabled_time_events
++;
376 if ((e
->enabled
= valid
)) {
378 e
->use_rtclock
= use_rtclock
;
379 pa_mainloop_wakeup(e
->mainloop
);
382 if (e
->mainloop
->cached_next_time_event
== e
)
383 e
->mainloop
->cached_next_time_event
= NULL
;
385 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
386 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
388 if (t
< e
->mainloop
->cached_next_time_event
->time
)
389 e
->mainloop
->cached_next_time_event
= e
;
393 static void mainloop_time_free(pa_time_event
*e
) {
398 e
->mainloop
->time_events_please_scan
++;
401 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
402 e
->mainloop
->n_enabled_time_events
--;
406 if (e
->mainloop
->cached_next_time_event
== e
)
407 e
->mainloop
->cached_next_time_event
= NULL
;
409 /* no wakeup needed here. Think about it! */
412 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
416 e
->destroy_callback
= callback
;
421 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
425 pa_assert(a
->userdata
);
427 pa_assert(a
== &m
->api
);
429 pa_mainloop_quit(m
, retval
);
432 static const pa_mainloop_api vtable
= {
435 .io_new
= mainloop_io_new
,
436 .io_enable
= mainloop_io_enable
,
437 .io_free
= mainloop_io_free
,
438 .io_set_destroy
= mainloop_io_set_destroy
,
440 .time_new
= mainloop_time_new
,
441 .time_restart
= mainloop_time_restart
,
442 .time_free
= mainloop_time_free
,
443 .time_set_destroy
= mainloop_time_set_destroy
,
445 .defer_new
= mainloop_defer_new
,
446 .defer_enable
= mainloop_defer_enable
,
447 .defer_free
= mainloop_defer_free
,
448 .defer_set_destroy
= mainloop_defer_set_destroy
,
450 .quit
= mainloop_quit
,
453 pa_mainloop
*pa_mainloop_new(void) {
458 m
= pa_xnew0(pa_mainloop
, 1);
460 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
461 pa_log_error("ERROR: cannot create wakeup pipe");
466 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
467 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
469 m
->rebuild_pollfds
= true;
474 m
->state
= STATE_PASSIVE
;
476 m
->poll_func_ret
= -1;
481 static void cleanup_io_events(pa_mainloop
*m
, bool force
) {
484 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
486 if (!force
&& m
->io_events_please_scan
<= 0)
489 if (force
|| e
->dead
) {
490 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
493 pa_assert(m
->io_events_please_scan
> 0);
494 m
->io_events_please_scan
--;
497 if (e
->destroy_callback
)
498 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
502 m
->rebuild_pollfds
= true;
506 pa_assert(m
->io_events_please_scan
== 0);
509 static void cleanup_time_events(pa_mainloop
*m
, bool force
) {
510 pa_time_event
*e
, *n
;
512 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
514 if (!force
&& m
->time_events_please_scan
<= 0)
517 if (force
|| e
->dead
) {
518 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
521 pa_assert(m
->time_events_please_scan
> 0);
522 m
->time_events_please_scan
--;
525 if (!e
->dead
&& e
->enabled
) {
526 pa_assert(m
->n_enabled_time_events
> 0);
527 m
->n_enabled_time_events
--;
531 if (e
->destroy_callback
)
532 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
538 pa_assert(m
->time_events_please_scan
== 0);
541 static void cleanup_defer_events(pa_mainloop
*m
, bool force
) {
542 pa_defer_event
*e
, *n
;
544 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
546 if (!force
&& m
->defer_events_please_scan
<= 0)
549 if (force
|| e
->dead
) {
550 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
553 pa_assert(m
->defer_events_please_scan
> 0);
554 m
->defer_events_please_scan
--;
557 if (!e
->dead
&& e
->enabled
) {
558 pa_assert(m
->n_enabled_defer_events
> 0);
559 m
->n_enabled_defer_events
--;
563 if (e
->destroy_callback
)
564 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
570 pa_assert(m
->defer_events_please_scan
== 0);
573 void pa_mainloop_free(pa_mainloop
*m
) {
576 cleanup_io_events(m
, true);
577 cleanup_defer_events(m
, true);
578 cleanup_time_events(m
, true);
580 pa_xfree(m
->pollfds
);
582 pa_close_pipe(m
->wakeup_pipe
);
587 static void scan_dead(pa_mainloop
*m
) {
590 if (m
->io_events_please_scan
)
591 cleanup_io_events(m
, false);
593 if (m
->time_events_please_scan
)
594 cleanup_time_events(m
, false);
596 if (m
->defer_events_please_scan
)
597 cleanup_defer_events(m
, false);
600 static void rebuild_pollfds(pa_mainloop
*m
) {
605 l
= m
->n_io_events
+ 1;
606 if (m
->max_pollfds
< l
) {
608 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
615 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
616 m
->pollfds
[0].events
= POLLIN
;
617 m
->pollfds
[0].revents
= 0;
621 PA_LLIST_FOREACH(e
, m
->io_events
) {
629 p
->events
= map_flags_to_libc(e
->events
);
636 m
->rebuild_pollfds
= false;
639 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
643 pa_assert(m
->poll_func_ret
> 0);
645 k
= m
->poll_func_ret
;
647 PA_LLIST_FOREACH(e
, m
->io_events
) {
649 if (k
<= 0 || m
->quit
)
652 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
655 pa_assert(e
->pollfd
->fd
== e
->fd
);
656 pa_assert(e
->callback
);
658 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
659 e
->pollfd
->revents
= 0;
667 static unsigned dispatch_defer(pa_mainloop
*m
) {
671 if (m
->n_enabled_defer_events
<= 0)
674 PA_LLIST_FOREACH(e
, m
->defer_events
) {
679 if (e
->dead
|| !e
->enabled
)
682 pa_assert(e
->callback
);
683 e
->callback(&m
->api
, e
, e
->userdata
);
690 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
691 pa_time_event
*t
, *n
= NULL
;
694 if (m
->cached_next_time_event
)
695 return m
->cached_next_time_event
;
697 PA_LLIST_FOREACH(t
, m
->time_events
) {
699 if (t
->dead
|| !t
->enabled
)
702 if (!n
|| t
->time
< n
->time
) {
705 /* Shortcut for time == 0 */
711 m
->cached_next_time_event
= n
;
715 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
719 if (m
->n_enabled_time_events
<= 0)
720 return PA_USEC_INVALID
;
722 pa_assert_se(t
= find_next_time_event(m
));
727 clock_now
= pa_rtclock_now();
729 if (t
->time
<= clock_now
)
732 return t
->time
- clock_now
;
735 static unsigned dispatch_timeout(pa_mainloop
*m
) {
741 if (m
->n_enabled_time_events
<= 0)
744 now
= pa_rtclock_now();
746 PA_LLIST_FOREACH(e
, m
->time_events
) {
751 if (e
->dead
|| !e
->enabled
)
754 if (e
->time
<= now
) {
756 pa_assert(e
->callback
);
758 /* Disable time event */
759 mainloop_time_restart(e
, NULL
);
761 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
770 void pa_mainloop_wakeup(pa_mainloop
*m
) {
774 if (pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
) < 0)
775 /* Not much options for recovering from the error. Let's at least log something. */
776 pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno
));
778 pa_atomic_store(&m
->wakeup_requested
, true);
781 static void clear_wakeup(pa_mainloop
*m
) {
786 if (pa_atomic_cmpxchg(&m
->wakeup_requested
, true, false)) {
787 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
792 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
794 pa_assert(m
->state
== STATE_PASSIVE
);
802 if (m
->n_enabled_defer_events
<= 0) {
804 if (m
->rebuild_pollfds
)
807 m
->prepared_timeout
= calc_next_timeout(m
);
809 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
811 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
812 m
->prepared_timeout
= timeout
;
816 m
->state
= STATE_PREPARED
;
820 m
->state
= STATE_QUIT
;
824 static int usec_to_timeout(pa_usec_t u
) {
827 if (u
== PA_USEC_INVALID
)
830 timeout
= (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
831 pa_assert(timeout
>= 0);
836 int pa_mainloop_poll(pa_mainloop
*m
) {
838 pa_assert(m
->state
== STATE_PREPARED
);
843 m
->state
= STATE_POLLING
;
845 if (m
->n_enabled_defer_events
)
846 m
->poll_func_ret
= 0;
848 pa_assert(!m
->rebuild_pollfds
);
851 m
->poll_func_ret
= m
->poll_func(
852 m
->pollfds
, m
->n_pollfds
,
853 usec_to_timeout(m
->prepared_timeout
),
854 m
->poll_func_userdata
);
859 m
->poll_func_ret
= ppoll(
860 m
->pollfds
, m
->n_pollfds
,
861 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
864 m
->poll_func_ret
= pa_poll(
865 m
->pollfds
, m
->n_pollfds
,
866 usec_to_timeout(m
->prepared_timeout
));
870 if (m
->poll_func_ret
< 0) {
872 m
->poll_func_ret
= 0;
874 pa_log("poll(): %s", pa_cstrerror(errno
));
878 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
879 return m
->poll_func_ret
;
882 m
->state
= STATE_QUIT
;
886 int pa_mainloop_dispatch(pa_mainloop
*m
) {
887 unsigned dispatched
= 0;
890 pa_assert(m
->state
== STATE_POLLED
);
895 if (m
->n_enabled_defer_events
)
896 dispatched
+= dispatch_defer(m
);
898 if (m
->n_enabled_time_events
)
899 dispatched
+= dispatch_timeout(m
);
904 if (m
->poll_func_ret
> 0)
905 dispatched
+= dispatch_pollfds(m
);
911 m
->state
= STATE_PASSIVE
;
913 return (int) dispatched
;
916 m
->state
= STATE_QUIT
;
920 int pa_mainloop_get_retval(pa_mainloop
*m
) {
926 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
930 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
933 if ((r
= pa_mainloop_poll(m
)) < 0)
936 if ((r
= pa_mainloop_dispatch(m
)) < 0)
943 if ((r
== -2) && retval
)
944 *retval
= pa_mainloop_get_retval(m
);
948 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
951 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
960 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
965 pa_mainloop_wakeup(m
);
968 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
974 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
977 m
->poll_func
= poll_func
;
978 m
->poll_func_userdata
= userdata
;
981 bool pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
984 return m
->io_new
== mainloop_io_new
;