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/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
;