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
38 #include <pulsecore/poll.h>
42 #include <pulsecore/pipe.h>
45 #include <pulse/i18n.h>
46 #include <pulse/rtclock.h>
47 #include <pulse/timeval.h>
48 #include <pulse/xmalloc.h>
50 #include <pulsecore/core-rtclock.h>
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/llist.h>
53 #include <pulsecore/log.h>
54 #include <pulsecore/core-error.h>
55 #include <pulsecore/winsock.h>
56 #include <pulsecore/macro.h>
62 pa_mainloop
*mainloop
;
66 pa_io_event_flags_t events
;
67 struct pollfd
*pollfd
;
69 pa_io_event_cb_t callback
;
71 pa_io_event_destroy_cb_t destroy_callback
;
73 PA_LLIST_FIELDS(pa_io_event
);
76 struct pa_time_event
{
77 pa_mainloop
*mainloop
;
83 pa_time_event_cb_t callback
;
85 pa_time_event_destroy_cb_t destroy_callback
;
87 PA_LLIST_FIELDS(pa_time_event
);
90 struct pa_defer_event
{
91 pa_mainloop
*mainloop
;
96 pa_defer_event_cb_t callback
;
98 pa_defer_event_destroy_cb_t destroy_callback
;
100 PA_LLIST_FIELDS(pa_defer_event
);
104 PA_LLIST_HEAD(pa_io_event
, io_events
);
105 PA_LLIST_HEAD(pa_time_event
, time_events
);
106 PA_LLIST_HEAD(pa_defer_event
, defer_events
);
108 unsigned n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
109 unsigned io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
111 pa_bool_t rebuild_pollfds
:1;
112 struct pollfd
*pollfds
;
113 unsigned max_pollfds
, n_pollfds
;
115 int prepared_timeout
;
116 pa_time_event
*cached_next_time_event
;
123 pa_bool_t wakeup_requested
:1;
125 int wakeup_pipe_type
;
135 pa_poll_func poll_func
;
136 void *poll_func_userdata
;
140 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
142 ((flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
143 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
144 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
145 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0));
148 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
150 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
151 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
152 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
153 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
157 static pa_io_event
* mainloop_io_new(
160 pa_io_event_flags_t events
,
161 pa_io_event_cb_t callback
,
168 pa_assert(a
->userdata
);
173 pa_assert(a
== &m
->api
);
175 e
= pa_xnew(pa_io_event
, 1);
183 e
->callback
= callback
;
184 e
->userdata
= userdata
;
185 e
->destroy_callback
= NULL
;
198 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
199 SELECT_TYPE_ARG5
&tv
) == -1) &&
200 (WSAGetLastError() == WSAENOTSOCK
)) {
201 pa_log_warn("Cannot monitor non-socket file descriptors.");
207 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
208 m
->rebuild_pollfds
= TRUE
;
211 pa_mainloop_wakeup(m
);
216 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
220 if (e
->events
== events
)
226 e
->pollfd
->events
= map_flags_to_libc(events
);
228 e
->mainloop
->rebuild_pollfds
= TRUE
;
230 pa_mainloop_wakeup(e
->mainloop
);
233 static void mainloop_io_free(pa_io_event
*e
) {
238 e
->mainloop
->io_events_please_scan
++;
240 e
->mainloop
->n_io_events
--;
241 e
->mainloop
->rebuild_pollfds
= TRUE
;
243 pa_mainloop_wakeup(e
->mainloop
);
246 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
249 e
->destroy_callback
= callback
;
253 static pa_defer_event
* mainloop_defer_new(
255 pa_defer_event_cb_t callback
,
262 pa_assert(a
->userdata
);
266 pa_assert(a
== &m
->api
);
268 e
= pa_xnew(pa_defer_event
, 1);
273 m
->n_enabled_defer_events
++;
275 e
->callback
= callback
;
276 e
->userdata
= userdata
;
277 e
->destroy_callback
= NULL
;
279 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
281 pa_mainloop_wakeup(e
->mainloop
);
286 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
290 if (e
->enabled
&& !b
) {
291 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
292 e
->mainloop
->n_enabled_defer_events
--;
293 } else if (!e
->enabled
&& b
) {
294 e
->mainloop
->n_enabled_defer_events
++;
295 pa_mainloop_wakeup(e
->mainloop
);
301 static void mainloop_defer_free(pa_defer_event
*e
) {
306 e
->mainloop
->defer_events_please_scan
++;
309 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
310 e
->mainloop
->n_enabled_defer_events
--;
315 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
319 e
->destroy_callback
= callback
;
323 static pa_usec_t
timeval_load(const struct timeval
*tv
) {
324 pa_bool_t is_rtclock
;
328 return PA_USEC_INVALID
;
331 is_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
332 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
335 pa_rtclock_from_wallclock(&ttv
);
337 return pa_timeval_load(&ttv
);
340 static pa_time_event
* mainloop_time_new(
342 const struct timeval
*tv
,
343 pa_time_event_cb_t callback
,
351 pa_assert(a
->userdata
);
354 t
= timeval_load(tv
);
357 pa_assert(a
== &m
->api
);
359 e
= pa_xnew(pa_time_event
, 1);
363 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
366 m
->n_enabled_time_events
++;
368 if (m
->cached_next_time_event
) {
369 pa_assert(m
->cached_next_time_event
->enabled
);
371 if (t
< m
->cached_next_time_event
->time
)
372 m
->cached_next_time_event
= e
;
376 e
->callback
= callback
;
377 e
->userdata
= userdata
;
378 e
->destroy_callback
= NULL
;
380 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
383 pa_mainloop_wakeup(m
);
388 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
395 t
= timeval_load(tv
);
397 valid
= (t
!= PA_USEC_INVALID
);
398 if (e
->enabled
&& !valid
) {
399 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
400 e
->mainloop
->n_enabled_time_events
--;
401 } else if (!e
->enabled
&& valid
)
402 e
->mainloop
->n_enabled_time_events
++;
404 if ((e
->enabled
= valid
)) {
406 pa_mainloop_wakeup(e
->mainloop
);
409 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
410 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
412 if (t
< e
->mainloop
->cached_next_time_event
->time
)
413 e
->mainloop
->cached_next_time_event
= e
;
414 } else if (e
->mainloop
->cached_next_time_event
== e
)
415 e
->mainloop
->cached_next_time_event
= NULL
;
418 static void mainloop_time_free(pa_time_event
*e
) {
423 e
->mainloop
->time_events_please_scan
++;
426 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
427 e
->mainloop
->n_enabled_time_events
--;
431 if (e
->mainloop
->cached_next_time_event
== e
)
432 e
->mainloop
->cached_next_time_event
= NULL
;
434 /* no wakeup needed here. Think about it! */
437 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
441 e
->destroy_callback
= callback
;
446 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
450 pa_assert(a
->userdata
);
452 pa_assert(a
== &m
->api
);
454 pa_mainloop_quit(m
, retval
);
457 static const pa_mainloop_api vtable
= {
460 .io_new
= mainloop_io_new
,
461 .io_enable
= mainloop_io_enable
,
462 .io_free
= mainloop_io_free
,
463 .io_set_destroy
= mainloop_io_set_destroy
,
465 .time_new
= mainloop_time_new
,
466 .time_restart
= mainloop_time_restart
,
467 .time_free
= mainloop_time_free
,
468 .time_set_destroy
= mainloop_time_set_destroy
,
470 .defer_new
= mainloop_defer_new
,
471 .defer_enable
= mainloop_defer_enable
,
472 .defer_free
= mainloop_defer_free
,
473 .defer_set_destroy
= mainloop_defer_set_destroy
,
475 .quit
= mainloop_quit
,
478 pa_mainloop
*pa_mainloop_new(void) {
483 m
= pa_xnew(pa_mainloop
, 1);
485 m
->wakeup_pipe_type
= 0;
486 if (pipe(m
->wakeup_pipe
) < 0) {
487 pa_log_error("ERROR: cannot create wakeup pipe");
492 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
493 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
494 pa_make_fd_cloexec(m
->wakeup_pipe
[0]);
495 pa_make_fd_cloexec(m
->wakeup_pipe
[1]);
496 m
->wakeup_requested
= FALSE
;
498 PA_LLIST_HEAD_INIT(pa_io_event
, m
->io_events
);
499 PA_LLIST_HEAD_INIT(pa_time_event
, m
->time_events
);
500 PA_LLIST_HEAD_INIT(pa_defer_event
, m
->defer_events
);
502 m
->n_enabled_defer_events
= m
->n_enabled_time_events
= m
->n_io_events
= 0;
503 m
->io_events_please_scan
= m
->time_events_please_scan
= m
->defer_events_please_scan
= 0;
505 m
->cached_next_time_event
= NULL
;
506 m
->prepared_timeout
= 0;
509 m
->max_pollfds
= m
->n_pollfds
= 0;
510 m
->rebuild_pollfds
= TRUE
;
518 m
->state
= STATE_PASSIVE
;
521 m
->poll_func_userdata
= NULL
;
522 m
->poll_func_ret
= -1;
527 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
532 pa_io_event
*n
= e
->next
;
534 if (!force
&& m
->io_events_please_scan
<= 0)
537 if (force
|| e
->dead
) {
538 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
541 pa_assert(m
->io_events_please_scan
> 0);
542 m
->io_events_please_scan
--;
545 if (e
->destroy_callback
)
546 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
550 m
->rebuild_pollfds
= TRUE
;
556 pa_assert(m
->io_events_please_scan
== 0);
559 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
564 pa_time_event
*n
= e
->next
;
566 if (!force
&& m
->time_events_please_scan
<= 0)
569 if (force
|| e
->dead
) {
570 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
573 pa_assert(m
->time_events_please_scan
> 0);
574 m
->time_events_please_scan
--;
577 if (!e
->dead
&& e
->enabled
) {
578 pa_assert(m
->n_enabled_time_events
> 0);
579 m
->n_enabled_time_events
--;
583 if (e
->destroy_callback
)
584 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
592 pa_assert(m
->time_events_please_scan
== 0);
595 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
600 pa_defer_event
*n
= e
->next
;
602 if (!force
&& m
->defer_events_please_scan
<= 0)
605 if (force
|| e
->dead
) {
606 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
609 pa_assert(m
->defer_events_please_scan
> 0);
610 m
->defer_events_please_scan
--;
613 if (!e
->dead
&& e
->enabled
) {
614 pa_assert(m
->n_enabled_defer_events
> 0);
615 m
->n_enabled_defer_events
--;
619 if (e
->destroy_callback
)
620 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
628 pa_assert(m
->defer_events_please_scan
== 0);
632 void pa_mainloop_free(pa_mainloop
* m
) {
635 cleanup_io_events(m
, TRUE
);
636 cleanup_defer_events(m
, TRUE
);
637 cleanup_time_events(m
, TRUE
);
639 pa_xfree(m
->pollfds
);
641 pa_close_pipe(m
->wakeup_pipe
);
646 static void scan_dead(pa_mainloop
*m
) {
649 if (m
->io_events_please_scan
)
650 cleanup_io_events(m
, FALSE
);
652 if (m
->time_events_please_scan
)
653 cleanup_time_events(m
, FALSE
);
655 if (m
->defer_events_please_scan
)
656 cleanup_defer_events(m
, FALSE
);
659 static void rebuild_pollfds(pa_mainloop
*m
) {
664 l
= m
->n_io_events
+ 1;
665 if (m
->max_pollfds
< l
) {
667 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
674 if (m
->wakeup_pipe
[0] >= 0) {
675 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
676 m
->pollfds
[0].events
= POLLIN
;
677 m
->pollfds
[0].revents
= 0;
682 for (e
= m
->io_events
; e
; e
= e
->next
) {
690 p
->events
= map_flags_to_libc(e
->events
);
697 m
->rebuild_pollfds
= FALSE
;
700 static int dispatch_pollfds(pa_mainloop
*m
) {
704 pa_assert(m
->poll_func_ret
> 0);
706 for (e
= m
->io_events
, k
= m
->poll_func_ret
; e
&& !m
->quit
&& k
> 0; e
= e
->next
) {
707 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
710 pa_assert(e
->pollfd
->fd
== e
->fd
);
711 pa_assert(e
->callback
);
712 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
713 e
->pollfd
->revents
= 0;
722 static int dispatch_defer(pa_mainloop
*m
) {
726 if (m
->n_enabled_defer_events
<= 0)
729 for (e
= m
->defer_events
; e
&& !m
->quit
; e
= e
->next
) {
730 if (e
->dead
|| !e
->enabled
)
733 pa_assert(e
->callback
);
734 e
->callback(&m
->api
, e
, e
->userdata
);
741 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
742 pa_time_event
*t
, *n
= NULL
;
745 if (m
->cached_next_time_event
)
746 return m
->cached_next_time_event
;
748 for (t
= m
->time_events
; t
; t
= t
->next
) {
750 if (t
->dead
|| !t
->enabled
)
753 if (!n
|| t
->time
< n
->time
) {
756 /* Shortcut for time == 0 */
762 m
->cached_next_time_event
= n
;
766 static int calc_next_timeout(pa_mainloop
*m
) {
770 if (!m
->n_enabled_time_events
)
773 pa_assert_se(t
= find_next_time_event(m
));
778 clock_now
= pa_rtclock_now();
780 if (t
->time
<= clock_now
)
783 return (int) ((t
->time
- clock_now
) / 1000); /* in milliseconds */
786 static int dispatch_timeout(pa_mainloop
*m
) {
792 if (m
->n_enabled_time_events
<= 0)
795 now
= pa_rtclock_now();
797 for (e
= m
->time_events
; e
&& !m
->quit
; e
= e
->next
) {
799 if (e
->dead
|| !e
->enabled
)
802 if (e
->time
<= now
) {
804 pa_assert(e
->callback
);
806 /* Disable time event */
807 mainloop_time_restart(e
, NULL
);
809 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, TRUE
), e
->userdata
);
818 void pa_mainloop_wakeup(pa_mainloop
*m
) {
822 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
823 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
824 m
->wakeup_requested
++;
828 static void clear_wakeup(pa_mainloop
*m
) {
833 if (m
->wakeup_pipe
[0] < 0)
836 if (m
->wakeup_requested
) {
837 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
));
838 m
->wakeup_requested
= 0;
842 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
844 pa_assert(m
->state
== STATE_PASSIVE
);
852 if (m
->n_enabled_defer_events
<= 0) {
853 if (m
->rebuild_pollfds
)
856 m
->prepared_timeout
= calc_next_timeout(m
);
857 if (timeout
>= 0 && (timeout
< m
->prepared_timeout
|| m
->prepared_timeout
< 0))
858 m
->prepared_timeout
= timeout
;
861 m
->state
= STATE_PREPARED
;
865 m
->state
= STATE_QUIT
;
869 int pa_mainloop_poll(pa_mainloop
*m
) {
871 pa_assert(m
->state
== STATE_PREPARED
);
876 m
->state
= STATE_POLLING
;
878 if (m
->n_enabled_defer_events
)
879 m
->poll_func_ret
= 0;
881 pa_assert(!m
->rebuild_pollfds
);
884 m
->poll_func_ret
= m
->poll_func(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
, m
->poll_func_userdata
);
886 m
->poll_func_ret
= poll(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
);
888 if (m
->poll_func_ret
< 0) {
890 m
->poll_func_ret
= 0;
892 pa_log("poll(): %s", pa_cstrerror(errno
));
896 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
897 return m
->poll_func_ret
;
900 m
->state
= STATE_QUIT
;
904 int pa_mainloop_dispatch(pa_mainloop
*m
) {
908 pa_assert(m
->state
== STATE_POLLED
);
913 if (m
->n_enabled_defer_events
)
914 dispatched
+= dispatch_defer(m
);
916 if (m
->n_enabled_time_events
)
917 dispatched
+= dispatch_timeout(m
);
922 if (m
->poll_func_ret
> 0)
923 dispatched
+= dispatch_pollfds(m
);
929 m
->state
= STATE_PASSIVE
;
934 m
->state
= STATE_QUIT
;
938 int pa_mainloop_get_retval(pa_mainloop
*m
) {
943 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
947 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
950 if ((r
= pa_mainloop_poll(m
)) < 0)
953 if ((r
= pa_mainloop_dispatch(m
)) < 0)
960 if ((r
== -2) && retval
)
961 *retval
= pa_mainloop_get_retval(m
);
965 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
968 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0);
978 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
983 pa_mainloop_wakeup(m
);
986 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
991 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
994 m
->poll_func
= poll_func
;
995 m
->poll_func_userdata
= userdata
;
998 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1001 return m
->io_new
== mainloop_io_new
;