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 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/timeval.h>
46 #include <pulse/xmalloc.h>
47 #include <pulse/i18n.h>
49 #include <pulsecore/core-util.h>
50 #include <pulsecore/llist.h>
51 #include <pulsecore/log.h>
52 #include <pulsecore/core-error.h>
53 #include <pulsecore/winsock.h>
54 #include <pulsecore/macro.h>
59 pa_mainloop
*mainloop
;
63 pa_io_event_flags_t events
;
64 struct pollfd
*pollfd
;
66 pa_io_event_cb_t callback
;
68 pa_io_event_destroy_cb_t destroy_callback
;
70 PA_LLIST_FIELDS(pa_io_event
);
73 struct pa_time_event
{
74 pa_mainloop
*mainloop
;
78 struct timeval timeval
;
80 pa_time_event_cb_t callback
;
82 pa_time_event_destroy_cb_t destroy_callback
;
84 PA_LLIST_FIELDS(pa_time_event
);
87 struct pa_defer_event
{
88 pa_mainloop
*mainloop
;
93 pa_defer_event_cb_t callback
;
95 pa_defer_event_destroy_cb_t destroy_callback
;
97 PA_LLIST_FIELDS(pa_defer_event
);
101 PA_LLIST_HEAD(pa_io_event
, io_events
);
102 PA_LLIST_HEAD(pa_time_event
, time_events
);
103 PA_LLIST_HEAD(pa_defer_event
, defer_events
);
105 unsigned n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
106 unsigned io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
108 pa_bool_t rebuild_pollfds
:1;
109 struct pollfd
*pollfds
;
110 unsigned max_pollfds
, n_pollfds
;
112 int prepared_timeout
;
113 pa_time_event
*cached_next_time_event
;
120 pa_bool_t wakeup_requested
:1;
122 int wakeup_pipe_type
;
132 pa_poll_func poll_func
;
133 void *poll_func_userdata
;
137 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
139 ((flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
140 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
141 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
142 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0));
145 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
147 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
148 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
149 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
150 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
154 static pa_io_event
* mainloop_io_new(
157 pa_io_event_flags_t events
,
158 pa_io_event_cb_t callback
,
165 pa_assert(a
->userdata
);
170 pa_assert(a
== &m
->api
);
172 e
= pa_xnew(pa_io_event
, 1);
180 e
->callback
= callback
;
181 e
->userdata
= userdata
;
182 e
->destroy_callback
= NULL
;
195 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
196 SELECT_TYPE_ARG5
&tv
) == -1) &&
197 (WSAGetLastError() == WSAENOTSOCK
)) {
198 pa_log_warn("Cannot monitor non-socket file descriptors.");
204 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
205 m
->rebuild_pollfds
= TRUE
;
208 pa_mainloop_wakeup(m
);
213 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
217 if (e
->events
== events
)
223 e
->pollfd
->events
= map_flags_to_libc(events
);
225 e
->mainloop
->rebuild_pollfds
= TRUE
;
227 pa_mainloop_wakeup(e
->mainloop
);
230 static void mainloop_io_free(pa_io_event
*e
) {
235 e
->mainloop
->io_events_please_scan
++;
237 e
->mainloop
->n_io_events
--;
238 e
->mainloop
->rebuild_pollfds
= TRUE
;
240 pa_mainloop_wakeup(e
->mainloop
);
243 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
246 e
->destroy_callback
= callback
;
250 static pa_defer_event
* mainloop_defer_new(
252 pa_defer_event_cb_t callback
,
259 pa_assert(a
->userdata
);
263 pa_assert(a
== &m
->api
);
265 e
= pa_xnew(pa_defer_event
, 1);
270 m
->n_enabled_defer_events
++;
272 e
->callback
= callback
;
273 e
->userdata
= userdata
;
274 e
->destroy_callback
= NULL
;
276 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
278 pa_mainloop_wakeup(e
->mainloop
);
283 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
287 if (e
->enabled
&& !b
) {
288 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
289 e
->mainloop
->n_enabled_defer_events
--;
290 } else if (!e
->enabled
&& b
) {
291 e
->mainloop
->n_enabled_defer_events
++;
292 pa_mainloop_wakeup(e
->mainloop
);
298 static void mainloop_defer_free(pa_defer_event
*e
) {
303 e
->mainloop
->defer_events_please_scan
++;
306 pa_assert(e
->mainloop
->n_enabled_defer_events
> 0);
307 e
->mainloop
->n_enabled_defer_events
--;
312 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
316 e
->destroy_callback
= callback
;
320 static pa_time_event
* mainloop_time_new(
322 const struct timeval
*tv
,
323 pa_time_event_cb_t callback
,
330 pa_assert(a
->userdata
);
334 pa_assert(a
== &m
->api
);
336 e
= pa_xnew(pa_time_event
, 1);
340 if ((e
->enabled
= !!tv
)) {
343 m
->n_enabled_time_events
++;
345 if (m
->cached_next_time_event
) {
346 pa_assert(m
->cached_next_time_event
->enabled
);
348 if (pa_timeval_cmp(tv
, &m
->cached_next_time_event
->timeval
) < 0)
349 m
->cached_next_time_event
= e
;
353 e
->callback
= callback
;
354 e
->userdata
= userdata
;
355 e
->destroy_callback
= NULL
;
357 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
360 pa_mainloop_wakeup(m
);
365 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
369 if (e
->enabled
&& !tv
) {
370 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
371 e
->mainloop
->n_enabled_time_events
--;
372 } else if (!e
->enabled
&& tv
)
373 e
->mainloop
->n_enabled_time_events
++;
375 if ((e
->enabled
= !!tv
)) {
377 pa_mainloop_wakeup(e
->mainloop
);
380 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
381 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
383 if (pa_timeval_cmp(tv
, &e
->mainloop
->cached_next_time_event
->timeval
) < 0)
384 e
->mainloop
->cached_next_time_event
= e
;
385 } else if (e
->mainloop
->cached_next_time_event
== e
)
386 e
->mainloop
->cached_next_time_event
= NULL
;
389 static void mainloop_time_free(pa_time_event
*e
) {
394 e
->mainloop
->time_events_please_scan
++;
397 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
398 e
->mainloop
->n_enabled_time_events
--;
402 if (e
->mainloop
->cached_next_time_event
== e
)
403 e
->mainloop
->cached_next_time_event
= NULL
;
405 /* no wakeup needed here. Think about it! */
408 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
412 e
->destroy_callback
= callback
;
417 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
421 pa_assert(a
->userdata
);
423 pa_assert(a
== &m
->api
);
425 pa_mainloop_quit(m
, retval
);
428 static const pa_mainloop_api vtable
= {
431 .io_new
= mainloop_io_new
,
432 .io_enable
= mainloop_io_enable
,
433 .io_free
= mainloop_io_free
,
434 .io_set_destroy
= mainloop_io_set_destroy
,
436 .time_new
= mainloop_time_new
,
437 .time_restart
= mainloop_time_restart
,
438 .time_free
= mainloop_time_free
,
439 .time_set_destroy
= mainloop_time_set_destroy
,
441 .defer_new
= mainloop_defer_new
,
442 .defer_enable
= mainloop_defer_enable
,
443 .defer_free
= mainloop_defer_free
,
444 .defer_set_destroy
= mainloop_defer_set_destroy
,
446 .quit
= mainloop_quit
,
449 pa_mainloop
*pa_mainloop_new(void) {
454 m
= pa_xnew(pa_mainloop
, 1);
456 m
->wakeup_pipe_type
= 0;
457 if (pipe(m
->wakeup_pipe
) < 0) {
458 pa_log_error("ERROR: cannot create wakeup pipe");
463 pa_make_fd_nonblock(m
->wakeup_pipe
[0]);
464 pa_make_fd_nonblock(m
->wakeup_pipe
[1]);
465 pa_make_fd_cloexec(m
->wakeup_pipe
[0]);
466 pa_make_fd_cloexec(m
->wakeup_pipe
[1]);
467 m
->wakeup_requested
= FALSE
;
469 PA_LLIST_HEAD_INIT(pa_io_event
, m
->io_events
);
470 PA_LLIST_HEAD_INIT(pa_time_event
, m
->time_events
);
471 PA_LLIST_HEAD_INIT(pa_defer_event
, m
->defer_events
);
473 m
->n_enabled_defer_events
= m
->n_enabled_time_events
= m
->n_io_events
= 0;
474 m
->io_events_please_scan
= m
->time_events_please_scan
= m
->defer_events_please_scan
= 0;
476 m
->cached_next_time_event
= NULL
;
477 m
->prepared_timeout
= 0;
480 m
->max_pollfds
= m
->n_pollfds
= 0;
481 m
->rebuild_pollfds
= TRUE
;
489 m
->state
= STATE_PASSIVE
;
492 m
->poll_func_userdata
= NULL
;
493 m
->poll_func_ret
= -1;
498 static void cleanup_io_events(pa_mainloop
*m
, pa_bool_t force
) {
503 pa_io_event
*n
= e
->next
;
505 if (!force
&& m
->io_events_please_scan
<= 0)
508 if (force
|| e
->dead
) {
509 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
512 pa_assert(m
->io_events_please_scan
> 0);
513 m
->io_events_please_scan
--;
516 if (e
->destroy_callback
)
517 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
521 m
->rebuild_pollfds
= TRUE
;
527 pa_assert(m
->io_events_please_scan
== 0);
530 static void cleanup_time_events(pa_mainloop
*m
, pa_bool_t force
) {
535 pa_time_event
*n
= e
->next
;
537 if (!force
&& m
->time_events_please_scan
<= 0)
540 if (force
|| e
->dead
) {
541 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
544 pa_assert(m
->time_events_please_scan
> 0);
545 m
->time_events_please_scan
--;
548 if (!e
->dead
&& e
->enabled
) {
549 pa_assert(m
->n_enabled_time_events
> 0);
550 m
->n_enabled_time_events
--;
554 if (e
->destroy_callback
)
555 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
563 pa_assert(m
->time_events_please_scan
== 0);
566 static void cleanup_defer_events(pa_mainloop
*m
, pa_bool_t force
) {
571 pa_defer_event
*n
= e
->next
;
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
);
599 pa_assert(m
->defer_events_please_scan
== 0);
603 void pa_mainloop_free(pa_mainloop
* m
) {
606 cleanup_io_events(m
, TRUE
);
607 cleanup_defer_events(m
, TRUE
);
608 cleanup_time_events(m
, TRUE
);
610 pa_xfree(m
->pollfds
);
612 pa_close_pipe(m
->wakeup_pipe
);
617 static void scan_dead(pa_mainloop
*m
) {
620 if (m
->io_events_please_scan
)
621 cleanup_io_events(m
, FALSE
);
623 if (m
->time_events_please_scan
)
624 cleanup_time_events(m
, FALSE
);
626 if (m
->defer_events_please_scan
)
627 cleanup_defer_events(m
, FALSE
);
630 static void rebuild_pollfds(pa_mainloop
*m
) {
635 l
= m
->n_io_events
+ 1;
636 if (m
->max_pollfds
< l
) {
638 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
645 if (m
->wakeup_pipe
[0] >= 0) {
646 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
647 m
->pollfds
[0].events
= POLLIN
;
648 m
->pollfds
[0].revents
= 0;
653 for (e
= m
->io_events
; e
; e
= e
->next
) {
661 p
->events
= map_flags_to_libc(e
->events
);
668 m
->rebuild_pollfds
= FALSE
;
671 static int dispatch_pollfds(pa_mainloop
*m
) {
675 pa_assert(m
->poll_func_ret
> 0);
677 for (e
= m
->io_events
, k
= m
->poll_func_ret
; e
&& !m
->quit
&& k
> 0; e
= e
->next
) {
678 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
681 pa_assert(e
->pollfd
->fd
== e
->fd
);
682 pa_assert(e
->callback
);
683 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
684 e
->pollfd
->revents
= 0;
693 static int dispatch_defer(pa_mainloop
*m
) {
697 if (m
->n_enabled_defer_events
<= 0)
700 for (e
= m
->defer_events
; e
&& !m
->quit
; e
= e
->next
) {
701 if (e
->dead
|| !e
->enabled
)
704 pa_assert(e
->callback
);
705 e
->callback(&m
->api
, e
, e
->userdata
);
712 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
713 pa_time_event
*t
, *n
= NULL
;
716 if (m
->cached_next_time_event
)
717 return m
->cached_next_time_event
;
719 for (t
= m
->time_events
; t
; t
= t
->next
) {
721 if (t
->dead
|| !t
->enabled
)
724 if (!n
|| pa_timeval_cmp(&t
->timeval
, &n
->timeval
) < 0) {
727 /* Shortcut for tv = { 0, 0 } */
728 if (n
->timeval
.tv_sec
<= 0)
733 m
->cached_next_time_event
= n
;
737 static int calc_next_timeout(pa_mainloop
*m
) {
742 if (!m
->n_enabled_time_events
)
745 t
= find_next_time_event(m
);
748 if (t
->timeval
.tv_sec
<= 0)
751 pa_gettimeofday(&now
);
753 if (pa_timeval_cmp(&t
->timeval
, &now
) <= 0)
756 usec
= pa_timeval_diff(&t
->timeval
, &now
);
757 return (int) (usec
/ 1000);
760 static int dispatch_timeout(pa_mainloop
*m
) {
766 if (m
->n_enabled_time_events
<= 0)
769 pa_gettimeofday(&now
);
771 for (e
= m
->time_events
; e
&& !m
->quit
; e
= e
->next
) {
773 if (e
->dead
|| !e
->enabled
)
776 if (pa_timeval_cmp(&e
->timeval
, &now
) <= 0) {
777 pa_assert(e
->callback
);
779 /* Disable time event */
780 mainloop_time_restart(e
, NULL
);
782 e
->callback(&m
->api
, e
, &e
->timeval
, 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
));
811 m
->wakeup_requested
= 0;
815 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
817 pa_assert(m
->state
== STATE_PASSIVE
);
825 if (m
->n_enabled_defer_events
<= 0) {
826 if (m
->rebuild_pollfds
)
829 m
->prepared_timeout
= calc_next_timeout(m
);
830 if (timeout
>= 0 && (timeout
< m
->prepared_timeout
|| m
->prepared_timeout
< 0))
831 m
->prepared_timeout
= timeout
;
834 m
->state
= STATE_PREPARED
;
838 m
->state
= STATE_QUIT
;
842 int pa_mainloop_poll(pa_mainloop
*m
) {
844 pa_assert(m
->state
== STATE_PREPARED
);
849 m
->state
= STATE_POLLING
;
851 if (m
->n_enabled_defer_events
)
852 m
->poll_func_ret
= 0;
854 pa_assert(!m
->rebuild_pollfds
);
857 m
->poll_func_ret
= m
->poll_func(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
, m
->poll_func_userdata
);
859 m
->poll_func_ret
= poll(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
);
861 if (m
->poll_func_ret
< 0) {
863 m
->poll_func_ret
= 0;
865 pa_log("poll(): %s", pa_cstrerror(errno
));
869 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
870 return m
->poll_func_ret
;
873 m
->state
= STATE_QUIT
;
877 int pa_mainloop_dispatch(pa_mainloop
*m
) {
881 pa_assert(m
->state
== STATE_POLLED
);
886 if (m
->n_enabled_defer_events
)
887 dispatched
+= dispatch_defer(m
);
889 if (m
->n_enabled_time_events
)
890 dispatched
+= dispatch_timeout(m
);
895 if (m
->poll_func_ret
> 0)
896 dispatched
+= dispatch_pollfds(m
);
902 m
->state
= STATE_PASSIVE
;
907 m
->state
= STATE_QUIT
;
911 int pa_mainloop_get_retval(pa_mainloop
*m
) {
916 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
920 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
923 if ((r
= pa_mainloop_poll(m
)) < 0)
926 if ((r
= pa_mainloop_dispatch(m
)) < 0)
933 if ((r
== -2) && retval
)
934 *retval
= pa_mainloop_get_retval(m
);
938 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
941 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0);
951 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
956 pa_mainloop_wakeup(m
);
959 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
964 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
967 m
->poll_func
= poll_func
;
968 m
->poll_func_userdata
= userdata
;