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/i18n.h>
38 #include <pulse/rtclock.h>
39 #include <pulse/timeval.h>
40 #include <pulse/xmalloc.h>
42 #include <pulsecore/poll.h>
43 #include <pulsecore/core-rtclock.h>
44 #include <pulsecore/core-util.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((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
190 SELECT_TYPE_ARG5
&tv
) == -1) &&
191 (WSAGetLastError() == WSAENOTSOCK
)) {
192 pa_log_warn("Cannot monitor non-socket file descriptors.");
198 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
199 m
->rebuild_pollfds
= TRUE
;
202 pa_mainloop_wakeup(m
);
207 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
211 if (e
->events
== events
)
217 e
->pollfd
->events
= map_flags_to_libc(events
);
219 e
->mainloop
->rebuild_pollfds
= TRUE
;
221 pa_mainloop_wakeup(e
->mainloop
);
224 static void mainloop_io_free(pa_io_event
*e
) {
229 e
->mainloop
->io_events_please_scan
++;
231 e
->mainloop
->n_io_events
--;
232 e
->mainloop
->rebuild_pollfds
= TRUE
;
234 pa_mainloop_wakeup(e
->mainloop
);
237 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
240 e
->destroy_callback
= callback
;
244 static pa_defer_event
* mainloop_defer_new(
246 pa_defer_event_cb_t callback
,
253 pa_assert(a
->userdata
);
257 pa_assert(a
== &m
->api
);
259 e
= pa_xnew0(pa_defer_event
, 1);
263 m
->n_enabled_defer_events
++;
265 e
->callback
= callback
;
266 e
->userdata
= userdata
;
268 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
270 pa_mainloop_wakeup(e
->mainloop
);
275 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
279 if (e
->enabled
&& !b
) {
280 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
281 e
->mainloop
->n_enabled_defer_events
--;
282 } else if (!e
->enabled
&& b
) {
283 e
->mainloop
->n_enabled_defer_events
++;
284 pa_mainloop_wakeup(e
->mainloop
);
290 static void mainloop_defer_free(pa_defer_event
*e
) {
295 e
->mainloop
->defer_events_please_scan
++;
298 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
299 e
->mainloop
->n_enabled_defer_events
--;
304 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
308 e
->destroy_callback
= callback
;
312 static pa_usec_t
make_rt(const struct timeval
*tv
, pa_bool_t
*use_rtclock
) {
316 *use_rtclock
= FALSE
;
317 return PA_USEC_INVALID
;
321 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
324 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
326 pa_rtclock_from_wallclock(&ttv
);
328 return pa_timeval_load(&ttv
);
331 static pa_time_event
* mainloop_time_new(
333 const struct timeval
*tv
,
334 pa_time_event_cb_t callback
,
340 pa_bool_t use_rtclock
= FALSE
;
343 pa_assert(a
->userdata
);
346 t
= make_rt(tv
, &use_rtclock
);
349 pa_assert(a
== &m
->api
);
351 e
= pa_xnew0(pa_time_event
, 1);
354 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
356 e
->use_rtclock
= use_rtclock
;
358 m
->n_enabled_time_events
++;
360 if (m
->cached_next_time_event
) {
361 pa_assert(m
->cached_next_time_event
->enabled
);
363 if (t
< m
->cached_next_time_event
->time
)
364 m
->cached_next_time_event
= e
;
368 e
->callback
= callback
;
369 e
->userdata
= userdata
;
371 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
374 pa_mainloop_wakeup(m
);
379 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
382 pa_bool_t use_rtclock
= FALSE
;
387 t
= make_rt(tv
, &use_rtclock
);
389 valid
= (t
!= PA_USEC_INVALID
);
390 if (e
->enabled
&& !valid
) {
391 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
392 e
->mainloop
->n_enabled_time_events
--;
393 } else if (!e
->enabled
&& valid
)
394 e
->mainloop
->n_enabled_time_events
++;
396 if ((e
->enabled
= valid
)) {
398 e
->use_rtclock
= use_rtclock
;
399 pa_mainloop_wakeup(e
->mainloop
);
402 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
403 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
405 if (t
< e
->mainloop
->cached_next_time_event
->time
)
406 e
->mainloop
->cached_next_time_event
= e
;
407 } else if (e
->mainloop
->cached_next_time_event
== e
)
408 e
->mainloop
->cached_next_time_event
= NULL
;
411 static void mainloop_time_free(pa_time_event
*e
) {
416 e
->mainloop
->time_events_please_scan
++;
419 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
420 e
->mainloop
->n_enabled_time_events
--;
424 if (e
->mainloop
->cached_next_time_event
== e
)
425 e
->mainloop
->cached_next_time_event
= NULL
;
427 /* no wakeup needed here. Think about it! */
430 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
434 e
->destroy_callback
= callback
;
439 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
443 pa_assert(a
->userdata
);
445 pa_assert(a
== &m
->api
);
447 pa_mainloop_quit(m
, retval
);
450 static const pa_mainloop_api vtable
= {
453 .io_new
= mainloop_io_new
,
454 .io_enable
= mainloop_io_enable
,
455 .io_free
= mainloop_io_free
,
456 .io_set_destroy
= mainloop_io_set_destroy
,
458 .time_new
= mainloop_time_new
,
459 .time_restart
= mainloop_time_restart
,
460 .time_free
= mainloop_time_free
,
461 .time_set_destroy
= mainloop_time_set_destroy
,
463 .defer_new
= mainloop_defer_new
,
464 .defer_enable
= mainloop_defer_enable
,
465 .defer_free
= mainloop_defer_free
,
466 .defer_set_destroy
= mainloop_defer_set_destroy
,
468 .quit
= mainloop_quit
,
471 pa_mainloop
*pa_mainloop_new(void) {
476 m
= pa_xnew0(pa_mainloop
, 1);
478 if (pa_pipe_cloexec(m
->wakeup_pipe
) < 0) {
479 pa_log_error("ERROR: cannot create wakeup pipe");
484 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
485 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
487 m
->rebuild_pollfds
= TRUE
;
492 m
->state
= STATE_PASSIVE
;
494 m
->poll_func_ret
= -1;
499 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
502 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
504 if (!force
&& m
->io_events_please_scan
<= 0)
507 if (force
|| e
->dead
) {
508 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
511 pa_assert(m
->io_events_please_scan
> 0);
512 m
->io_events_please_scan
--;
515 if (e
->destroy_callback
)
516 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
520 m
->rebuild_pollfds
= TRUE
;
524 pa_assert(m
->io_events_please_scan
== 0);
527 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
528 pa_time_event
*e
, *n
;
530 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
532 if (!force
&& m
->time_events_please_scan
<= 0)
535 if (force
|| e
->dead
) {
536 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
539 pa_assert(m
->time_events_please_scan
> 0);
540 m
->time_events_please_scan
--;
543 if (!e
->dead
&& e
->enabled
) {
544 pa_assert(m
->n_enabled_time_events
> 0);
545 m
->n_enabled_time_events
--;
549 if (e
->destroy_callback
)
550 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
556 pa_assert(m
->time_events_please_scan
== 0);
559 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
560 pa_defer_event
*e
, *n
;
562 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
564 if (!force
&& m
->defer_events_please_scan
<= 0)
567 if (force
|| e
->dead
) {
568 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
571 pa_assert(m
->defer_events_please_scan
> 0);
572 m
->defer_events_please_scan
--;
575 if (!e
->dead
&& e
->enabled
) {
576 pa_assert(m
->n_enabled_defer_events
> 0);
577 m
->n_enabled_defer_events
--;
581 if (e
->destroy_callback
)
582 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
588 pa_assert(m
->defer_events_please_scan
== 0);
592 void pa_mainloop_free(pa_mainloop
*m
) {
595 cleanup_io_events(m
, TRUE
);
596 cleanup_defer_events(m
, TRUE
);
597 cleanup_time_events(m
, TRUE
);
599 pa_xfree(m
->pollfds
);
601 pa_close_pipe(m
->wakeup_pipe
);
606 static void scan_dead(pa_mainloop
*m
) {
609 if (m
->io_events_please_scan
)
610 cleanup_io_events(m
, FALSE
);
612 if (m
->time_events_please_scan
)
613 cleanup_time_events(m
, FALSE
);
615 if (m
->defer_events_please_scan
)
616 cleanup_defer_events(m
, FALSE
);
619 static void rebuild_pollfds(pa_mainloop
*m
) {
624 l
= m
->n_io_events
+ 1;
625 if (m
->max_pollfds
< l
) {
627 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
634 if (m
->wakeup_pipe
[0] >= 0) {
635 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
636 m
->pollfds
[0].events
= POLLIN
;
637 m
->pollfds
[0].revents
= 0;
642 PA_LLIST_FOREACH(e
, m
->io_events
) {
650 p
->events
= map_flags_to_libc(e
->events
);
657 m
->rebuild_pollfds
= FALSE
;
660 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
664 pa_assert(m
->poll_func_ret
> 0);
666 k
= m
->poll_func_ret
;
668 PA_LLIST_FOREACH(e
, m
->io_events
) {
670 if (k
<= 0 || m
->quit
)
673 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
676 pa_assert(e
->pollfd
->fd
== e
->fd
);
677 pa_assert(e
->callback
);
679 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
680 e
->pollfd
->revents
= 0;
688 static unsigned dispatch_defer(pa_mainloop
*m
) {
692 if (m
->n_enabled_defer_events
<= 0)
695 PA_LLIST_FOREACH(e
, m
->defer_events
) {
700 if (e
->dead
|| !e
->enabled
)
703 pa_assert(e
->callback
);
704 e
->callback(&m
->api
, e
, e
->userdata
);
711 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
712 pa_time_event
*t
, *n
= NULL
;
715 if (m
->cached_next_time_event
)
716 return m
->cached_next_time_event
;
718 PA_LLIST_FOREACH(t
, m
->time_events
) {
720 if (t
->dead
|| !t
->enabled
)
723 if (!n
|| t
->time
< n
->time
) {
726 /* Shortcut for time == 0 */
732 m
->cached_next_time_event
= n
;
736 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
740 if (m
->n_enabled_time_events
<= 0)
741 return PA_USEC_INVALID
;
743 pa_assert_se(t
= find_next_time_event(m
));
748 clock_now
= pa_rtclock_now();
750 if (t
->time
<= clock_now
)
753 return t
->time
- clock_now
;
756 static unsigned dispatch_timeout(pa_mainloop
*m
) {
762 if (m
->n_enabled_time_events
<= 0)
765 now
= pa_rtclock_now();
767 PA_LLIST_FOREACH(e
, m
->time_events
) {
772 if (e
->dead
|| !e
->enabled
)
775 if (e
->time
<= now
) {
777 pa_assert(e
->callback
);
779 /* Disable time event */
780 mainloop_time_restart(e
, NULL
);
782 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
791 void pa_mainloop_wakeup(pa_mainloop
*m
) {
795 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
796 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
797 m
->wakeup_requested
++;
801 static void clear_wakeup(pa_mainloop
*m
) {
806 if (m
->wakeup_pipe
[0] < 0)
809 if (m
->wakeup_requested
) {
810 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
812 m
->wakeup_requested
= 0;
816 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
818 pa_assert(m
->state
== STATE_PASSIVE
);
826 if (m
->n_enabled_defer_events
<= 0) {
828 if (m
->rebuild_pollfds
)
831 m
->prepared_timeout
= calc_next_timeout(m
);
833 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
835 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
836 m
->prepared_timeout
= timeout
;
840 m
->state
= STATE_PREPARED
;
844 m
->state
= STATE_QUIT
;
848 static int usec_to_timeout(pa_usec_t u
) {
851 if (u
== PA_USEC_INVALID
)
854 timeout
= (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
855 pa_assert(timeout
>= 0);
860 int pa_mainloop_poll(pa_mainloop
*m
) {
862 pa_assert(m
->state
== STATE_PREPARED
);
867 m
->state
= STATE_POLLING
;
869 if (m
->n_enabled_defer_events
)
870 m
->poll_func_ret
= 0;
872 pa_assert(!m
->rebuild_pollfds
);
875 m
->poll_func_ret
= m
->poll_func(
876 m
->pollfds
, m
->n_pollfds
,
877 usec_to_timeout(m
->prepared_timeout
),
878 m
->poll_func_userdata
);
883 m
->poll_func_ret
= ppoll(
884 m
->pollfds
, m
->n_pollfds
,
885 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
888 m
->poll_func_ret
= pa_poll(
889 m
->pollfds
, m
->n_pollfds
,
890 usec_to_timeout(m
->prepared_timeout
));
894 if (m
->poll_func_ret
< 0) {
896 m
->poll_func_ret
= 0;
898 pa_log("poll(): %s", pa_cstrerror(errno
));
902 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
903 return m
->poll_func_ret
;
906 m
->state
= STATE_QUIT
;
910 int pa_mainloop_dispatch(pa_mainloop
*m
) {
911 unsigned dispatched
= 0;
914 pa_assert(m
->state
== STATE_POLLED
);
919 if (m
->n_enabled_defer_events
)
920 dispatched
+= dispatch_defer(m
);
922 if (m
->n_enabled_time_events
)
923 dispatched
+= dispatch_timeout(m
);
928 if (m
->poll_func_ret
> 0)
929 dispatched
+= dispatch_pollfds(m
);
935 m
->state
= STATE_PASSIVE
;
937 return (int) dispatched
;
940 m
->state
= STATE_QUIT
;
944 int pa_mainloop_get_retval(pa_mainloop
*m
) {
950 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
954 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
957 if ((r
= pa_mainloop_poll(m
)) < 0)
960 if ((r
= pa_mainloop_dispatch(m
)) < 0)
967 if ((r
== -2) && retval
)
968 *retval
= pa_mainloop_get_retval(m
);
972 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
975 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
986 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
991 pa_mainloop_wakeup(m
);
994 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
1000 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
1003 m
->poll_func
= poll_func
;
1004 m
->poll_func_userdata
= userdata
;
1007 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1010 return m
->io_new
== mainloop_io_new
;