4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
7 Copyright 2006 Pierre Ossman <ossman@cendio.se> for Cendio AB
9 PulseAudio is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published
11 by the Free Software Foundation; either version 2 of the License,
12 or (at your option) any later version.
14 PulseAudio is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with PulseAudio; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
37 #ifdef HAVE_SYS_POLL_H
40 #include <pulsecore/poll.h>
44 #include <pulsecore/pipe.h>
47 #include <pulse/timeval.h>
48 #include <pulse/xmalloc.h>
50 #include <pulsecore/core-util.h>
51 #include <pulsecore/llist.h>
52 #include <pulsecore/log.h>
53 #include <pulsecore/core-error.h>
54 #include <pulsecore/winsock.h>
55 #include <pulsecore/macro.h>
60 pa_mainloop
*mainloop
;
64 pa_io_event_flags_t events
;
65 struct pollfd
*pollfd
;
67 pa_io_event_cb_t callback
;
69 pa_io_event_destroy_cb_t destroy_callback
;
71 PA_LLIST_FIELDS(pa_io_event
);
74 struct pa_time_event
{
75 pa_mainloop
*mainloop
;
79 struct timeval timeval
;
81 pa_time_event_cb_t callback
;
83 pa_time_event_destroy_cb_t destroy_callback
;
85 PA_LLIST_FIELDS(pa_time_event
);
88 struct pa_defer_event
{
89 pa_mainloop
*mainloop
;
94 pa_defer_event_cb_t callback
;
96 pa_defer_event_destroy_cb_t destroy_callback
;
98 PA_LLIST_FIELDS(pa_defer_event
);
102 PA_LLIST_HEAD(pa_io_event
, io_events
);
103 PA_LLIST_HEAD(pa_time_event
, time_events
);
104 PA_LLIST_HEAD(pa_defer_event
, defer_events
);
106 int n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
107 int io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
109 struct pollfd
*pollfds
;
110 unsigned max_pollfds
, n_pollfds
;
113 int prepared_timeout
;
114 pa_time_event
*cached_next_time_event
;
120 int wakeup_pipe_type
;
121 int wakeup_requested
;
131 pa_poll_func poll_func
;
132 void *poll_func_userdata
;
136 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
138 (flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
139 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
140 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
141 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0);
144 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
146 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
147 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
148 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
149 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
153 static pa_io_event
* mainloop_io_new(
156 pa_io_event_flags_t events
,
157 pa_io_event_cb_t callback
,
164 pa_assert(a
->userdata
);
169 pa_assert(a
== &m
->api
);
171 e
= pa_xnew(pa_io_event
, 1);
179 e
->callback
= callback
;
180 e
->userdata
= userdata
;
181 e
->destroy_callback
= NULL
;
194 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
195 SELECT_TYPE_ARG5
&tv
) == -1) &&
196 (WSAGetLastError() == WSAENOTSOCK
)) {
197 pa_log_warn("WARNING: cannot monitor non-socket file descriptors.");
203 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
204 m
->rebuild_pollfds
= 1;
207 pa_mainloop_wakeup(m
);
212 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
216 if (e
->events
== events
)
222 e
->pollfd
->events
= map_flags_to_libc(events
);
224 e
->mainloop
->rebuild_pollfds
= 1;
226 pa_mainloop_wakeup(e
->mainloop
);
229 static void mainloop_io_free(pa_io_event
*e
) {
234 e
->mainloop
->io_events_please_scan
++;
236 e
->mainloop
->n_io_events
--;
237 e
->mainloop
->rebuild_pollfds
= 1;
239 pa_mainloop_wakeup(e
->mainloop
);
242 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
245 e
->destroy_callback
= callback
;
249 static pa_defer_event
* mainloop_defer_new(
251 pa_defer_event_cb_t callback
,
258 pa_assert(a
->userdata
);
262 pa_assert(a
== &m
->api
);
264 e
= pa_xnew(pa_defer_event
, 1);
269 m
->n_enabled_defer_events
++;
271 e
->callback
= callback
;
272 e
->userdata
= userdata
;
273 e
->destroy_callback
= NULL
;
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_time_event
* mainloop_time_new(
321 const struct timeval
*tv
,
322 pa_time_event_cb_t callback
,
329 pa_assert(a
->userdata
);
333 pa_assert(a
== &m
->api
);
335 e
= pa_xnew(pa_time_event
, 1);
339 if ((e
->enabled
= !!tv
)) {
342 m
->n_enabled_time_events
++;
344 if (m
->cached_next_time_event
) {
345 pa_assert(m
->cached_next_time_event
->enabled
);
347 if (pa_timeval_cmp(tv
, &m
->cached_next_time_event
->timeval
) < 0)
348 m
->cached_next_time_event
= e
;
352 e
->callback
= callback
;
353 e
->userdata
= userdata
;
354 e
->destroy_callback
= NULL
;
356 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
359 pa_mainloop_wakeup(m
);
364 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
368 if (e
->enabled
&& !tv
) {
369 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
370 e
->mainloop
->n_enabled_time_events
--;
371 } else if (!e
->enabled
&& tv
)
372 e
->mainloop
->n_enabled_time_events
++;
374 if ((e
->enabled
= !!tv
)) {
376 pa_mainloop_wakeup(e
->mainloop
);
379 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
380 pa_assert(e
->mainloop
->cached_next_time_event
->enabled
);
382 if (pa_timeval_cmp(tv
, &e
->mainloop
->cached_next_time_event
->timeval
) < 0)
383 e
->mainloop
->cached_next_time_event
= e
;
384 } else if (e
->mainloop
->cached_next_time_event
== e
)
385 e
->mainloop
->cached_next_time_event
= NULL
;
388 static void mainloop_time_free(pa_time_event
*e
) {
393 e
->mainloop
->time_events_please_scan
++;
396 pa_assert(e
->mainloop
->n_enabled_time_events
> 0);
397 e
->mainloop
->n_enabled_time_events
--;
401 if (e
->mainloop
->cached_next_time_event
== e
)
402 e
->mainloop
->cached_next_time_event
= NULL
;
404 /* no wakeup needed here. Think about it! */
407 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
411 e
->destroy_callback
= callback
;
416 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
420 pa_assert(a
->userdata
);
422 pa_assert(a
== &m
->api
);
424 pa_mainloop_quit(m
, retval
);
427 static const pa_mainloop_api vtable
= {
430 .io_new
= mainloop_io_new
,
431 .io_enable
= mainloop_io_enable
,
432 .io_free
= mainloop_io_free
,
433 .io_set_destroy
= mainloop_io_set_destroy
,
435 .time_new
= mainloop_time_new
,
436 .time_restart
= mainloop_time_restart
,
437 .time_free
= mainloop_time_free
,
438 .time_set_destroy
= mainloop_time_set_destroy
,
440 .defer_new
= mainloop_defer_new
,
441 .defer_enable
= mainloop_defer_enable
,
442 .defer_free
= mainloop_defer_free
,
443 .defer_set_destroy
= mainloop_defer_set_destroy
,
445 .quit
= mainloop_quit
,
448 pa_mainloop
*pa_mainloop_new(void) {
451 m
= pa_xnew(pa_mainloop
, 1);
453 m
->wakeup_pipe_type
= 0;
454 if (pipe(m
->wakeup_pipe
) < 0) {
455 pa_log_error("ERROR: cannot create wakeup pipe");
460 pa_make_nonblock_fd(m
->wakeup_pipe
[0]);
461 pa_make_nonblock_fd(m
->wakeup_pipe
[1]);
462 pa_fd_set_cloexec(m
->wakeup_pipe
[0], 1);
463 pa_fd_set_cloexec(m
->wakeup_pipe
[1], 1);
464 m
->wakeup_requested
= 0;
466 PA_LLIST_HEAD_INIT(pa_io_event
, m
->io_events
);
467 PA_LLIST_HEAD_INIT(pa_time_event
, m
->time_events
);
468 PA_LLIST_HEAD_INIT(pa_defer_event
, m
->defer_events
);
470 m
->n_enabled_defer_events
= m
->n_enabled_time_events
= m
->n_io_events
= 0;
471 m
->io_events_please_scan
= m
->time_events_please_scan
= m
->defer_events_please_scan
= 0;
473 m
->cached_next_time_event
= NULL
;
474 m
->prepared_timeout
= 0;
477 m
->max_pollfds
= m
->n_pollfds
= 0;
478 m
->rebuild_pollfds
= 1;
480 m
->quit
= m
->retval
= 0;
485 m
->state
= STATE_PASSIVE
;
488 m
->poll_func_userdata
= NULL
;
489 m
->poll_func_ret
= -1;
494 static void cleanup_io_events(pa_mainloop
*m
, int force
) {
499 pa_io_event
*n
= e
->next
;
501 if (!force
&& m
->io_events_please_scan
<= 0)
504 if (force
|| e
->dead
) {
505 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
508 pa_assert(m
->io_events_please_scan
> 0);
509 m
->io_events_please_scan
--;
512 if (e
->destroy_callback
)
513 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
517 m
->rebuild_pollfds
= 1;
523 pa_assert(m
->io_events_please_scan
== 0);
526 static void cleanup_time_events(pa_mainloop
*m
, int force
) {
531 pa_time_event
*n
= e
->next
;
533 if (!force
&& m
->time_events_please_scan
<= 0)
536 if (force
|| e
->dead
) {
537 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
540 pa_assert(m
->time_events_please_scan
> 0);
541 m
->time_events_please_scan
--;
544 if (!e
->dead
&& e
->enabled
) {
545 pa_assert(m
->n_enabled_time_events
> 0);
546 m
->n_enabled_time_events
--;
550 if (e
->destroy_callback
)
551 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
559 pa_assert(m
->time_events_please_scan
== 0);
562 static void cleanup_defer_events(pa_mainloop
*m
, int force
) {
567 pa_defer_event
*n
= e
->next
;
569 if (!force
&& m
->defer_events_please_scan
<= 0)
572 if (force
|| e
->dead
) {
573 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
576 pa_assert(m
->defer_events_please_scan
> 0);
577 m
->defer_events_please_scan
--;
580 if (!e
->dead
&& e
->enabled
) {
581 pa_assert(m
->n_enabled_defer_events
> 0);
582 m
->n_enabled_defer_events
--;
586 if (e
->destroy_callback
)
587 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
595 pa_assert(m
->defer_events_please_scan
== 0);
599 void pa_mainloop_free(pa_mainloop
* m
) {
602 cleanup_io_events(m
, 1);
603 cleanup_defer_events(m
, 1);
604 cleanup_time_events(m
, 1);
606 pa_xfree(m
->pollfds
);
608 if (m
->wakeup_pipe
[0] >= 0)
609 close(m
->wakeup_pipe
[0]);
610 if (m
->wakeup_pipe
[1] >= 0)
611 close(m
->wakeup_pipe
[1]);
616 static void scan_dead(pa_mainloop
*m
) {
619 if (m
->io_events_please_scan
)
620 cleanup_io_events(m
, 0);
622 if (m
->time_events_please_scan
)
623 cleanup_time_events(m
, 0);
625 if (m
->defer_events_please_scan
)
626 cleanup_defer_events(m
, 0);
629 static void rebuild_pollfds(pa_mainloop
*m
) {
634 l
= m
->n_io_events
+ 1;
635 if (m
->max_pollfds
< l
) {
637 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
644 if (m
->wakeup_pipe
[0] >= 0) {
645 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
646 m
->pollfds
[0].events
= POLLIN
;
647 m
->pollfds
[0].revents
= 0;
652 for (e
= m
->io_events
; e
; e
= e
->next
) {
660 p
->events
= map_flags_to_libc(e
->events
);
667 m
->rebuild_pollfds
= 0;
670 static int dispatch_pollfds(pa_mainloop
*m
) {
674 pa_assert(m
->poll_func_ret
> 0);
676 for (e
= m
->io_events
, k
= m
->poll_func_ret
; e
&& !m
->quit
&& k
> 0; e
= e
->next
) {
677 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
680 pa_assert(e
->pollfd
->fd
== e
->fd
&& e
->callback
);
681 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
682 e
->pollfd
->revents
= 0;
691 static int dispatch_defer(pa_mainloop
*m
) {
695 if (m
->n_enabled_defer_events
<= 0)
698 for (e
= m
->defer_events
; e
&& !m
->quit
; e
= e
->next
) {
699 if (e
->dead
|| !e
->enabled
)
702 pa_assert(e
->callback
);
703 e
->callback(&m
->api
, e
, e
->userdata
);
710 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
711 pa_time_event
*t
, *n
= NULL
;
714 if (m
->cached_next_time_event
)
715 return m
->cached_next_time_event
;
717 for (t
= m
->time_events
; t
; t
= t
->next
) {
719 if (t
->dead
|| !t
->enabled
)
722 if (!n
|| pa_timeval_cmp(&t
->timeval
, &n
->timeval
) < 0) {
725 /* Shortcut for tv = { 0, 0 } */
726 if (n
->timeval
.tv_sec
<= 0)
731 m
->cached_next_time_event
= n
;
735 static int calc_next_timeout(pa_mainloop
*m
) {
740 if (!m
->n_enabled_time_events
)
743 t
= find_next_time_event(m
);
746 if (t
->timeval
.tv_sec
<= 0)
749 pa_gettimeofday(&now
);
751 if (pa_timeval_cmp(&t
->timeval
, &now
) <= 0)
754 usec
= pa_timeval_diff(&t
->timeval
, &now
);
755 return (int) (usec
/ 1000);
758 static int dispatch_timeout(pa_mainloop
*m
) {
764 if (m
->n_enabled_time_events
<= 0)
767 pa_gettimeofday(&now
);
769 for (e
= m
->time_events
; e
&& !m
->quit
; e
= e
->next
) {
771 if (e
->dead
|| !e
->enabled
)
774 if (pa_timeval_cmp(&e
->timeval
, &now
) <= 0) {
775 pa_assert(e
->callback
);
777 /* Disable time event */
778 mainloop_time_restart(e
, NULL
);
780 e
->callback(&m
->api
, e
, &e
->timeval
, e
->userdata
);
789 void pa_mainloop_wakeup(pa_mainloop
*m
) {
793 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
794 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
795 m
->wakeup_requested
++;
799 static void clear_wakeup(pa_mainloop
*m
) {
804 if (m
->wakeup_pipe
[0] < 0)
807 if (m
->wakeup_requested
) {
808 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
));
809 m
->wakeup_requested
= 0;
813 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
815 pa_assert(m
->state
== STATE_PASSIVE
);
823 if (m
->n_enabled_defer_events
<= 0) {
824 if (m
->rebuild_pollfds
)
827 m
->prepared_timeout
= calc_next_timeout(m
);
828 if (timeout
>= 0 && (timeout
< m
->prepared_timeout
|| m
->prepared_timeout
< 0))
829 m
->prepared_timeout
= timeout
;
832 m
->state
= STATE_PREPARED
;
836 m
->state
= STATE_QUIT
;
840 int pa_mainloop_poll(pa_mainloop
*m
) {
842 pa_assert(m
->state
== STATE_PREPARED
);
847 m
->state
= STATE_POLLING
;
849 if (m
->n_enabled_defer_events
)
850 m
->poll_func_ret
= 0;
852 pa_assert(!m
->rebuild_pollfds
);
855 m
->poll_func_ret
= m
->poll_func(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
, m
->poll_func_userdata
);
857 m
->poll_func_ret
= poll(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
);
859 if (m
->poll_func_ret
< 0) {
861 m
->poll_func_ret
= 0;
863 pa_log("poll(): %s", pa_cstrerror(errno
));
867 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
868 return m
->poll_func_ret
;
871 m
->state
= STATE_QUIT
;
875 int pa_mainloop_dispatch(pa_mainloop
*m
) {
879 pa_assert(m
->state
== STATE_POLLED
);
884 if (m
->n_enabled_defer_events
)
885 dispatched
+= dispatch_defer(m
);
887 if (m
->n_enabled_time_events
)
888 dispatched
+= dispatch_timeout(m
);
893 if (m
->poll_func_ret
> 0)
894 dispatched
+= dispatch_pollfds(m
);
900 m
->state
= STATE_PASSIVE
;
905 m
->state
= STATE_QUIT
;
909 int pa_mainloop_get_retval(pa_mainloop
*m
) {
914 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
918 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
921 if ((r
= pa_mainloop_poll(m
)) < 0)
924 if ((r
= pa_mainloop_dispatch(m
)) < 0)
931 if ((r
== -2) && retval
)
932 *retval
= pa_mainloop_get_retval(m
);
936 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
939 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0);
949 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
954 pa_mainloop_wakeup(m
);
957 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
962 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
965 m
->poll_func
= poll_func
;
966 m
->poll_func_userdata
= userdata
;