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
->enabled
) {
383 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
385 if (t
< e
->mainloop
->cached_next_time_event
->time
)
386 e
->mainloop
->cached_next_time_event
= e
;
387 } else if (e
->mainloop
->cached_next_time_event
== e
)
388 e
->mainloop
->cached_next_time_event
= NULL
;
391 static void mainloop_time_free(pa_time_event
*e
) {
396 e
->mainloop
->time_events_please_scan
++;
399 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
400 e
->mainloop
->n_enabled_time_events
--;
404 if (e
->mainloop
->cached_next_time_event
== e
)
405 e
->mainloop
->cached_next_time_event
= NULL
;
407 /* no wakeup needed here. Think about it! */
410 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
414 e
->destroy_callback
= callback
;
419 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
423 pa_assert(a
->userdata
);
425 pa_assert(a
== &m
->api
);
427 pa_mainloop_quit(m
, retval
);
430 static const pa_mainloop_api vtable
= {
433 .io_new
= mainloop_io_new
,
434 .io_enable
= mainloop_io_enable
,
435 .io_free
= mainloop_io_free
,
436 .io_set_destroy
= mainloop_io_set_destroy
,
438 .time_new
= mainloop_time_new
,
439 .time_restart
= mainloop_time_restart
,
440 .time_free
= mainloop_time_free
,
441 .time_set_destroy
= mainloop_time_set_destroy
,
443 .defer_new
= mainloop_defer_new
,
444 .defer_enable
= mainloop_defer_enable
,
445 .defer_free
= mainloop_defer_free
,
446 .defer_set_destroy
= mainloop_defer_set_destroy
,
448 .quit
= mainloop_quit
,
451 pa_mainloop
*pa_mainloop_new(void) {
456 m
= pa_xnew0(pa_mainloop
, 1);
458 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
459 pa_log_error("ERROR: cannot create wakeup pipe");
464 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
465 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
467 m
->rebuild_pollfds
= true;
472 m
->state
= STATE_PASSIVE
;
474 m
->poll_func_ret
= -1;
479 static void cleanup_io_events(pa_mainloop
*m
, bool force
) {
482 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
484 if (!force
&& m
->io_events_please_scan
<= 0)
487 if (force
|| e
->dead
) {
488 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
491 pa_assert(m
->io_events_please_scan
> 0);
492 m
->io_events_please_scan
--;
495 if (e
->destroy_callback
)
496 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
500 m
->rebuild_pollfds
= true;
504 pa_assert(m
->io_events_please_scan
== 0);
507 static void cleanup_time_events(pa_mainloop
*m
, bool force
) {
508 pa_time_event
*e
, *n
;
510 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
512 if (!force
&& m
->time_events_please_scan
<= 0)
515 if (force
|| e
->dead
) {
516 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
519 pa_assert(m
->time_events_please_scan
> 0);
520 m
->time_events_please_scan
--;
523 if (!e
->dead
&& e
->enabled
) {
524 pa_assert(m
->n_enabled_time_events
> 0);
525 m
->n_enabled_time_events
--;
529 if (e
->destroy_callback
)
530 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
536 pa_assert(m
->time_events_please_scan
== 0);
539 static void cleanup_defer_events(pa_mainloop
*m
, bool force
) {
540 pa_defer_event
*e
, *n
;
542 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
544 if (!force
&& m
->defer_events_please_scan
<= 0)
547 if (force
|| e
->dead
) {
548 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
551 pa_assert(m
->defer_events_please_scan
> 0);
552 m
->defer_events_please_scan
--;
555 if (!e
->dead
&& e
->enabled
) {
556 pa_assert(m
->n_enabled_defer_events
> 0);
557 m
->n_enabled_defer_events
--;
561 if (e
->destroy_callback
)
562 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
568 pa_assert(m
->defer_events_please_scan
== 0);
571 void pa_mainloop_free(pa_mainloop
*m
) {
574 cleanup_io_events(m
, true);
575 cleanup_defer_events(m
, true);
576 cleanup_time_events(m
, true);
578 pa_xfree(m
->pollfds
);
580 pa_close_pipe(m
->wakeup_pipe
);
585 static void scan_dead(pa_mainloop
*m
) {
588 if (m
->io_events_please_scan
)
589 cleanup_io_events(m
, false);
591 if (m
->time_events_please_scan
)
592 cleanup_time_events(m
, false);
594 if (m
->defer_events_please_scan
)
595 cleanup_defer_events(m
, false);
598 static void rebuild_pollfds(pa_mainloop
*m
) {
603 l
= m
->n_io_events
+ 1;
604 if (m
->max_pollfds
< l
) {
606 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
613 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
614 m
->pollfds
[0].events
= POLLIN
;
615 m
->pollfds
[0].revents
= 0;
619 PA_LLIST_FOREACH(e
, m
->io_events
) {
627 p
->events
= map_flags_to_libc(e
->events
);
634 m
->rebuild_pollfds
= false;
637 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
641 pa_assert(m
->poll_func_ret
> 0);
643 k
= m
->poll_func_ret
;
645 PA_LLIST_FOREACH(e
, m
->io_events
) {
647 if (k
<= 0 || m
->quit
)
650 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
653 pa_assert(e
->pollfd
->fd
== e
->fd
);
654 pa_assert(e
->callback
);
656 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
657 e
->pollfd
->revents
= 0;
665 static unsigned dispatch_defer(pa_mainloop
*m
) {
669 if (m
->n_enabled_defer_events
<= 0)
672 PA_LLIST_FOREACH(e
, m
->defer_events
) {
677 if (e
->dead
|| !e
->enabled
)
680 pa_assert(e
->callback
);
681 e
->callback(&m
->api
, e
, e
->userdata
);
688 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
689 pa_time_event
*t
, *n
= NULL
;
692 if (m
->cached_next_time_event
)
693 return m
->cached_next_time_event
;
695 PA_LLIST_FOREACH(t
, m
->time_events
) {
697 if (t
->dead
|| !t
->enabled
)
700 if (!n
|| t
->time
< n
->time
) {
703 /* Shortcut for time == 0 */
709 m
->cached_next_time_event
= n
;
713 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
717 if (m
->n_enabled_time_events
<= 0)
718 return PA_USEC_INVALID
;
720 pa_assert_se(t
= find_next_time_event(m
));
725 clock_now
= pa_rtclock_now();
727 if (t
->time
<= clock_now
)
730 return t
->time
- clock_now
;
733 static unsigned dispatch_timeout(pa_mainloop
*m
) {
739 if (m
->n_enabled_time_events
<= 0)
742 now
= pa_rtclock_now();
744 PA_LLIST_FOREACH(e
, m
->time_events
) {
749 if (e
->dead
|| !e
->enabled
)
752 if (e
->time
<= now
) {
754 pa_assert(e
->callback
);
756 /* Disable time event */
757 mainloop_time_restart(e
, NULL
);
759 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
768 void pa_mainloop_wakeup(pa_mainloop
*m
) {
772 if (pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
) < 0)
773 /* Not much options for recovering from the error. Let's at least log something. */
774 pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno
));
776 pa_atomic_store(&m
->wakeup_requested
, true);
779 static void clear_wakeup(pa_mainloop
*m
) {
784 if (pa_atomic_cmpxchg(&m
->wakeup_requested
, true, false)) {
785 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
790 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
792 pa_assert(m
->state
== STATE_PASSIVE
);
800 if (m
->n_enabled_defer_events
<= 0) {
802 if (m
->rebuild_pollfds
)
805 m
->prepared_timeout
= calc_next_timeout(m
);
807 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
809 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
810 m
->prepared_timeout
= timeout
;
814 m
->state
= STATE_PREPARED
;
818 m
->state
= STATE_QUIT
;
822 static int usec_to_timeout(pa_usec_t u
) {
825 if (u
== PA_USEC_INVALID
)
828 timeout
= (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
829 pa_assert(timeout
>= 0);
834 int pa_mainloop_poll(pa_mainloop
*m
) {
836 pa_assert(m
->state
== STATE_PREPARED
);
841 m
->state
= STATE_POLLING
;
843 if (m
->n_enabled_defer_events
)
844 m
->poll_func_ret
= 0;
846 pa_assert(!m
->rebuild_pollfds
);
849 m
->poll_func_ret
= m
->poll_func(
850 m
->pollfds
, m
->n_pollfds
,
851 usec_to_timeout(m
->prepared_timeout
),
852 m
->poll_func_userdata
);
857 m
->poll_func_ret
= ppoll(
858 m
->pollfds
, m
->n_pollfds
,
859 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
862 m
->poll_func_ret
= pa_poll(
863 m
->pollfds
, m
->n_pollfds
,
864 usec_to_timeout(m
->prepared_timeout
));
868 if (m
->poll_func_ret
< 0) {
870 m
->poll_func_ret
= 0;
872 pa_log("poll(): %s", pa_cstrerror(errno
));
876 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
877 return m
->poll_func_ret
;
880 m
->state
= STATE_QUIT
;
884 int pa_mainloop_dispatch(pa_mainloop
*m
) {
885 unsigned dispatched
= 0;
888 pa_assert(m
->state
== STATE_POLLED
);
893 if (m
->n_enabled_defer_events
)
894 dispatched
+= dispatch_defer(m
);
896 if (m
->n_enabled_time_events
)
897 dispatched
+= dispatch_timeout(m
);
902 if (m
->poll_func_ret
> 0)
903 dispatched
+= dispatch_pollfds(m
);
909 m
->state
= STATE_PASSIVE
;
911 return (int) dispatched
;
914 m
->state
= STATE_QUIT
;
918 int pa_mainloop_get_retval(pa_mainloop
*m
) {
924 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
928 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
931 if ((r
= pa_mainloop_poll(m
)) < 0)
934 if ((r
= pa_mainloop_dispatch(m
)) < 0)
941 if ((r
== -2) && retval
)
942 *retval
= pa_mainloop_get_retval(m
);
946 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
949 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
;