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
;
81 pa_bool_t use_rtclock
:1;
84 pa_time_event_cb_t callback
;
86 pa_time_event_destroy_cb_t destroy_callback
;
88 PA_LLIST_FIELDS(pa_time_event
);
91 struct pa_defer_event
{
92 pa_mainloop
*mainloop
;
97 pa_defer_event_cb_t callback
;
99 pa_defer_event_destroy_cb_t destroy_callback
;
101 PA_LLIST_FIELDS(pa_defer_event
);
105 PA_LLIST_HEAD(pa_io_event
, io_events
);
106 PA_LLIST_HEAD(pa_time_event
, time_events
);
107 PA_LLIST_HEAD(pa_defer_event
, defer_events
);
109 unsigned n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
110 unsigned io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
112 pa_bool_t rebuild_pollfds
:1;
113 struct pollfd
*pollfds
;
114 unsigned max_pollfds
, n_pollfds
;
116 pa_usec_t prepared_timeout
;
117 pa_time_event
*cached_next_time_event
;
124 pa_bool_t wakeup_requested
:1;
126 int wakeup_pipe_type
;
136 pa_poll_func poll_func
;
137 void *poll_func_userdata
;
141 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
143 ((flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
144 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
145 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
146 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0));
149 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
151 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
152 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
153 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
154 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
158 static pa_io_event
* mainloop_io_new(
161 pa_io_event_flags_t events
,
162 pa_io_event_cb_t callback
,
169 pa_assert(a
->userdata
);
174 pa_assert(a
== &m
->api
);
176 e
= pa_xnew0(pa_io_event
, 1);
182 e
->callback
= callback
;
183 e
->userdata
= userdata
;
196 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
197 SELECT_TYPE_ARG5
&tv
) == -1) &&
198 (WSAGetLastError() == WSAENOTSOCK
)) {
199 pa_log_warn("Cannot monitor non-socket file descriptors.");
205 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
206 m
->rebuild_pollfds
= TRUE
;
209 pa_mainloop_wakeup(m
);
214 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
218 if (e
->events
== events
)
224 e
->pollfd
->events
= map_flags_to_libc(events
);
226 e
->mainloop
->rebuild_pollfds
= TRUE
;
228 pa_mainloop_wakeup(e
->mainloop
);
231 static void mainloop_io_free(pa_io_event
*e
) {
236 e
->mainloop
->io_events_please_scan
++;
238 e
->mainloop
->n_io_events
--;
239 e
->mainloop
->rebuild_pollfds
= TRUE
;
241 pa_mainloop_wakeup(e
->mainloop
);
244 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
247 e
->destroy_callback
= callback
;
251 static pa_defer_event
* mainloop_defer_new(
253 pa_defer_event_cb_t callback
,
260 pa_assert(a
->userdata
);
264 pa_assert(a
== &m
->api
);
266 e
= pa_xnew0(pa_defer_event
, 1);
270 m
->n_enabled_defer_events
++;
272 e
->callback
= callback
;
273 e
->userdata
= userdata
;
275 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
277 pa_mainloop_wakeup(e
->mainloop
);
282 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
286 if (e
->enabled
&& !b
) {
287 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
288 e
->mainloop
->n_enabled_defer_events
--;
289 } else if (!e
->enabled
&& b
) {
290 e
->mainloop
->n_enabled_defer_events
++;
291 pa_mainloop_wakeup(e
->mainloop
);
297 static void mainloop_defer_free(pa_defer_event
*e
) {
302 e
->mainloop
->defer_events_please_scan
++;
305 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
306 e
->mainloop
->n_enabled_defer_events
--;
311 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
315 e
->destroy_callback
= callback
;
319 static pa_usec_t
make_rt(const struct timeval
*tv
, pa_bool_t
*use_rtclock
) {
323 *use_rtclock
= FALSE
;
324 return PA_USEC_INVALID
;
328 *use_rtclock
= !!(ttv
.tv_usec
& PA_TIMEVAL_RTCLOCK
);
331 ttv
.tv_usec
&= ~PA_TIMEVAL_RTCLOCK
;
333 pa_rtclock_from_wallclock(&ttv
);
335 return pa_timeval_load(&ttv
);
338 static pa_time_event
* mainloop_time_new(
340 const struct timeval
*tv
,
341 pa_time_event_cb_t callback
,
347 pa_bool_t use_rtclock
= FALSE
;
350 pa_assert(a
->userdata
);
353 t
= make_rt(tv
, &use_rtclock
);
356 pa_assert(a
== &m
->api
);
358 e
= pa_xnew0(pa_time_event
, 1);
361 if ((e
->enabled
= (t
!= PA_USEC_INVALID
))) {
363 e
->use_rtclock
= use_rtclock
;
365 m
->n_enabled_time_events
++;
367 if (m
->cached_next_time_event
) {
368 pa_assert(m
->cached_next_time_event
->enabled
);
370 if (t
< m
->cached_next_time_event
->time
)
371 m
->cached_next_time_event
= e
;
375 e
->callback
= callback
;
376 e
->userdata
= userdata
;
378 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
381 pa_mainloop_wakeup(m
);
386 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
389 pa_bool_t use_rtclock
= FALSE
;
394 t
= make_rt(tv
, &use_rtclock
);
396 valid
= (t
!= PA_USEC_INVALID
);
397 if (e
->enabled
&& !valid
) {
398 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
399 e
->mainloop
->n_enabled_time_events
--;
400 } else if (!e
->enabled
&& valid
)
401 e
->mainloop
->n_enabled_time_events
++;
403 if ((e
->enabled
= valid
)) {
405 e
->use_rtclock
= use_rtclock
;
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_xnew0(pa_mainloop
, 1);
485 if (pipe(m
->wakeup_pipe
) < 0) {
486 pa_log_error("ERROR: cannot create wakeup pipe");
491 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
492 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
493 pa_make_fd_cloexec(m
->wakeup_pipe
[0]);
494 pa_make_fd_cloexec(m
->wakeup_pipe
[1]);
496 m
->rebuild_pollfds
= TRUE
;
501 m
->state
= STATE_PASSIVE
;
503 m
->poll_func_ret
= -1;
508 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
511 PA_LLIST_FOREACH_SAFE(e
, n
, m
->io_events
) {
513 if (!force
&& m
->io_events_please_scan
<= 0)
516 if (force
|| e
->dead
) {
517 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
520 pa_assert(m
->io_events_please_scan
> 0);
521 m
->io_events_please_scan
--;
524 if (e
->destroy_callback
)
525 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
529 m
->rebuild_pollfds
= TRUE
;
533 pa_assert(m
->io_events_please_scan
== 0);
536 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
537 pa_time_event
*e
, *n
;
539 PA_LLIST_FOREACH_SAFE(e
, n
, m
->time_events
) {
541 if (!force
&& m
->time_events_please_scan
<= 0)
544 if (force
|| e
->dead
) {
545 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
548 pa_assert(m
->time_events_please_scan
> 0);
549 m
->time_events_please_scan
--;
552 if (!e
->dead
&& e
->enabled
) {
553 pa_assert(m
->n_enabled_time_events
> 0);
554 m
->n_enabled_time_events
--;
558 if (e
->destroy_callback
)
559 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
565 pa_assert(m
->time_events_please_scan
== 0);
568 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
569 pa_defer_event
*e
, *n
;
571 PA_LLIST_FOREACH_SAFE(e
, n
, m
->defer_events
) {
573 if (!force
&& m
->defer_events_please_scan
<= 0)
576 if (force
|| e
->dead
) {
577 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
580 pa_assert(m
->defer_events_please_scan
> 0);
581 m
->defer_events_please_scan
--;
584 if (!e
->dead
&& e
->enabled
) {
585 pa_assert(m
->n_enabled_defer_events
> 0);
586 m
->n_enabled_defer_events
--;
590 if (e
->destroy_callback
)
591 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
597 pa_assert(m
->defer_events_please_scan
== 0);
601 void pa_mainloop_free(pa_mainloop
* m
) {
604 cleanup_io_events(m
, TRUE
);
605 cleanup_defer_events(m
, TRUE
);
606 cleanup_time_events(m
, TRUE
);
608 pa_xfree(m
->pollfds
);
610 pa_close_pipe(m
->wakeup_pipe
);
615 static void scan_dead(pa_mainloop
*m
) {
618 if (m
->io_events_please_scan
)
619 cleanup_io_events(m
, FALSE
);
621 if (m
->time_events_please_scan
)
622 cleanup_time_events(m
, FALSE
);
624 if (m
->defer_events_please_scan
)
625 cleanup_defer_events(m
, FALSE
);
628 static void rebuild_pollfds(pa_mainloop
*m
) {
633 l
= m
->n_io_events
+ 1;
634 if (m
->max_pollfds
< l
) {
636 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
643 if (m
->wakeup_pipe
[0] >= 0) {
644 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
645 m
->pollfds
[0].events
= POLLIN
;
646 m
->pollfds
[0].revents
= 0;
651 PA_LLIST_FOREACH(e
, m
->io_events
) {
659 p
->events
= map_flags_to_libc(e
->events
);
666 m
->rebuild_pollfds
= FALSE
;
669 static unsigned dispatch_pollfds(pa_mainloop
*m
) {
673 pa_assert(m
->poll_func_ret
> 0);
675 k
= m
->poll_func_ret
;
677 PA_LLIST_FOREACH(e
, m
->io_events
) {
679 if (k
<= 0 || m
->quit
)
682 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
685 pa_assert(e
->pollfd
->fd
== e
->fd
);
686 pa_assert(e
->callback
);
688 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
689 e
->pollfd
->revents
= 0;
697 static unsigned dispatch_defer(pa_mainloop
*m
) {
701 if (m
->n_enabled_defer_events
<= 0)
704 PA_LLIST_FOREACH(e
, m
->defer_events
) {
709 if (e
->dead
|| !e
->enabled
)
712 pa_assert(e
->callback
);
713 e
->callback(&m
->api
, e
, e
->userdata
);
720 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
721 pa_time_event
*t
, *n
= NULL
;
724 if (m
->cached_next_time_event
)
725 return m
->cached_next_time_event
;
727 PA_LLIST_FOREACH(t
, m
->time_events
) {
729 if (t
->dead
|| !t
->enabled
)
732 if (!n
|| t
->time
< n
->time
) {
735 /* Shortcut for time == 0 */
741 m
->cached_next_time_event
= n
;
745 static pa_usec_t
calc_next_timeout(pa_mainloop
*m
) {
749 if (m
->n_enabled_time_events
<= 0)
750 return PA_USEC_INVALID
;
752 pa_assert_se(t
= find_next_time_event(m
));
757 clock_now
= pa_rtclock_now();
759 if (t
->time
<= clock_now
)
762 return t
->time
- clock_now
;
765 static unsigned dispatch_timeout(pa_mainloop
*m
) {
771 if (m
->n_enabled_time_events
<= 0)
774 now
= pa_rtclock_now();
776 PA_LLIST_FOREACH(e
, m
->time_events
) {
781 if (e
->dead
|| !e
->enabled
)
784 if (e
->time
<= now
) {
786 pa_assert(e
->callback
);
788 /* Disable time event */
789 mainloop_time_restart(e
, NULL
);
791 e
->callback(&m
->api
, e
, pa_timeval_rtstore(&tv
, e
->time
, e
->use_rtclock
), e
->userdata
);
800 void pa_mainloop_wakeup(pa_mainloop
*m
) {
804 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
805 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
806 m
->wakeup_requested
++;
810 static void clear_wakeup(pa_mainloop
*m
) {
815 if (m
->wakeup_pipe
[0] < 0)
818 if (m
->wakeup_requested
) {
819 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
))
821 m
->wakeup_requested
= 0;
825 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
827 pa_assert(m
->state
== STATE_PASSIVE
);
835 if (m
->n_enabled_defer_events
<= 0) {
837 if (m
->rebuild_pollfds
)
840 m
->prepared_timeout
= calc_next_timeout(m
);
842 uint64_t u
= (uint64_t) timeout
* PA_USEC_PER_MSEC
;
844 if (u
< m
->prepared_timeout
|| m
->prepared_timeout
== PA_USEC_INVALID
)
845 m
->prepared_timeout
= timeout
;
849 m
->state
= STATE_PREPARED
;
853 m
->state
= STATE_QUIT
;
857 static int usec_to_timeout(pa_usec_t u
) {
858 if (u
== PA_USEC_INVALID
)
861 return (u
+ PA_USEC_PER_MSEC
- 1) / PA_USEC_PER_MSEC
;
864 int pa_mainloop_poll(pa_mainloop
*m
) {
866 pa_assert(m
->state
== STATE_PREPARED
);
871 m
->state
= STATE_POLLING
;
873 if (m
->n_enabled_defer_events
)
874 m
->poll_func_ret
= 0;
876 pa_assert(!m
->rebuild_pollfds
);
879 m
->poll_func_ret
= m
->poll_func(
880 m
->pollfds
, m
->n_pollfds
,
881 usec_to_timeout(m
->prepared_timeout
),
882 m
->poll_func_userdata
);
887 m
->poll_func_ret
= ppoll(
888 m
->pollfds
, m
->n_pollfds
,
889 m
->prepared_timeout
== PA_USEC_INVALID
? NULL
: pa_timespec_store(&ts
, m
->prepared_timeout
),
892 m
->poll_func_ret
= poll(
893 m
->pollfds
, m
->n_pollfds
,
894 usec_to_timeout(m
->prepared_timeout
));
898 if (m
->poll_func_ret
< 0) {
900 m
->poll_func_ret
= 0;
902 pa_log("poll(): %s", pa_cstrerror(errno
));
906 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
907 return m
->poll_func_ret
;
910 m
->state
= STATE_QUIT
;
914 int pa_mainloop_dispatch(pa_mainloop
*m
) {
915 unsigned dispatched
= 0;
918 pa_assert(m
->state
== STATE_POLLED
);
923 if (m
->n_enabled_defer_events
)
924 dispatched
+= dispatch_defer(m
);
926 if (m
->n_enabled_time_events
)
927 dispatched
+= dispatch_timeout(m
);
932 if (m
->poll_func_ret
> 0)
933 dispatched
+= dispatch_pollfds(m
);
939 m
->state
= STATE_PASSIVE
;
941 return (int) dispatched
;
944 m
->state
= STATE_QUIT
;
948 int pa_mainloop_get_retval(pa_mainloop
*m
) {
954 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
958 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
961 if ((r
= pa_mainloop_poll(m
)) < 0)
964 if ((r
= pa_mainloop_dispatch(m
)) < 0)
971 if ((r
== -2) && retval
)
972 *retval
= pa_mainloop_get_retval(m
);
976 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
979 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0)
990 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
995 pa_mainloop_wakeup(m
);
998 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
1004 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
1007 m
->poll_func
= poll_func
;
1008 m
->poll_func_userdata
= userdata
;
1011 pa_bool_t
pa_mainloop_is_our_api(pa_mainloop_api
*m
) {
1014 return m
->io_new
== mainloop_io_new
;