4 This file is part of PulseAudio.
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
35 #ifdef HAVE_SYS_POLL_H
38 #include "../pulsecore/poll.h"
41 #include "../pulsecore/winsock.h"
44 #include "../pulsecore/pipe.h"
47 #include <pulsecore/core-error.h>
48 #include <pulse/timeval.h>
49 #include <pulse/xmalloc.h>
51 #include <pulsecore/core-util.h>
52 #include <pulsecore/llist.h>
53 #include <pulsecore/log.h>
58 pa_mainloop
*mainloop
;
62 pa_io_event_flags_t events
;
63 struct pollfd
*pollfd
;
65 pa_io_event_cb_t callback
;
67 pa_io_event_destroy_cb_t destroy_callback
;
69 PA_LLIST_FIELDS(pa_io_event
);
72 struct pa_time_event
{
73 pa_mainloop
*mainloop
;
77 struct timeval timeval
;
79 pa_time_event_cb_t callback
;
81 pa_time_event_destroy_cb_t destroy_callback
;
83 PA_LLIST_FIELDS(pa_time_event
);
86 struct pa_defer_event
{
87 pa_mainloop
*mainloop
;
92 pa_defer_event_cb_t callback
;
94 pa_defer_event_destroy_cb_t destroy_callback
;
96 PA_LLIST_FIELDS(pa_defer_event
);
100 PA_LLIST_HEAD(pa_io_event
, io_events
);
101 PA_LLIST_HEAD(pa_time_event
, time_events
);
102 PA_LLIST_HEAD(pa_defer_event
, defer_events
);
104 int n_enabled_defer_events
, n_enabled_time_events
, n_io_events
;
105 int io_events_please_scan
, time_events_please_scan
, defer_events_please_scan
;
107 struct pollfd
*pollfds
;
108 unsigned max_pollfds
, n_pollfds
;
111 int prepared_timeout
;
112 pa_time_event
*cached_next_time_event
;
118 int wakeup_pipe_type
;
119 int wakeup_requested
;
129 pa_poll_func poll_func
;
130 void *poll_func_userdata
;
134 static short map_flags_to_libc(pa_io_event_flags_t flags
) {
136 (flags
& PA_IO_EVENT_INPUT
? POLLIN
: 0) |
137 (flags
& PA_IO_EVENT_OUTPUT
? POLLOUT
: 0) |
138 (flags
& PA_IO_EVENT_ERROR
? POLLERR
: 0) |
139 (flags
& PA_IO_EVENT_HANGUP
? POLLHUP
: 0);
142 static pa_io_event_flags_t
map_flags_from_libc(short flags
) {
144 (flags
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
145 (flags
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
146 (flags
& POLLERR
? PA_IO_EVENT_ERROR
: 0) |
147 (flags
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0);
151 static pa_io_event
* mainloop_io_new(
154 pa_io_event_flags_t events
,
155 pa_io_event_cb_t callback
,
167 assert(a
== &m
->api
);
169 e
= pa_xnew(pa_io_event
, 1);
177 e
->callback
= callback
;
178 e
->userdata
= userdata
;
179 e
->destroy_callback
= NULL
;
192 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
193 SELECT_TYPE_ARG5
&tv
) == -1) &&
194 (WSAGetLastError() == WSAENOTSOCK
)) {
195 pa_log_warn(__FILE__
": WARNING: cannot monitor non-socket file descriptors.");
201 PA_LLIST_PREPEND(pa_io_event
, m
->io_events
, e
);
202 m
->rebuild_pollfds
= 1;
205 pa_mainloop_wakeup(m
);
210 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
214 if (e
->events
== events
)
220 e
->pollfd
->events
= map_flags_to_libc(events
);
222 e
->mainloop
->rebuild_pollfds
= 1;
224 pa_mainloop_wakeup(e
->mainloop
);
227 static void mainloop_io_free(pa_io_event
*e
) {
232 e
->mainloop
->io_events_please_scan
++;
234 e
->mainloop
->n_io_events
--;
235 e
->mainloop
->rebuild_pollfds
= 1;
237 pa_mainloop_wakeup(e
->mainloop
);
240 static void mainloop_io_set_destroy(pa_io_event
*e
, pa_io_event_destroy_cb_t callback
) {
243 e
->destroy_callback
= callback
;
247 static pa_defer_event
* mainloop_defer_new(
249 pa_defer_event_cb_t callback
,
260 assert(a
== &m
->api
);
262 e
= pa_xnew(pa_defer_event
, 1);
267 m
->n_enabled_defer_events
++;
269 e
->callback
= callback
;
270 e
->userdata
= userdata
;
271 e
->destroy_callback
= NULL
;
273 PA_LLIST_PREPEND(pa_defer_event
, m
->defer_events
, e
);
275 pa_mainloop_wakeup(e
->mainloop
);
280 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
284 if (e
->enabled
&& !b
) {
285 assert(e
->mainloop
->n_enabled_defer_events
> 0);
286 e
->mainloop
->n_enabled_defer_events
--;
287 } else if (!e
->enabled
&& b
) {
288 e
->mainloop
->n_enabled_defer_events
++;
289 pa_mainloop_wakeup(e
->mainloop
);
295 static void mainloop_defer_free(pa_defer_event
*e
) {
300 e
->mainloop
->defer_events_please_scan
++;
303 assert(e
->mainloop
->n_enabled_defer_events
> 0);
304 e
->mainloop
->n_enabled_defer_events
--;
308 static void mainloop_defer_set_destroy(pa_defer_event
*e
, pa_defer_event_destroy_cb_t callback
) {
312 e
->destroy_callback
= callback
;
316 static pa_time_event
* mainloop_time_new(
318 const struct timeval
*tv
,
319 pa_time_event_cb_t callback
,
330 assert(a
== &m
->api
);
332 e
= pa_xnew(pa_time_event
, 1);
336 if ((e
->enabled
= !!tv
)) {
339 m
->n_enabled_time_events
++;
341 if (m
->cached_next_time_event
) {
342 assert(m
->cached_next_time_event
->enabled
);
344 if (pa_timeval_cmp(tv
, &m
->cached_next_time_event
->timeval
) < 0)
345 m
->cached_next_time_event
= e
;
349 e
->callback
= callback
;
350 e
->userdata
= userdata
;
351 e
->destroy_callback
= NULL
;
353 PA_LLIST_PREPEND(pa_time_event
, m
->time_events
, e
);
356 pa_mainloop_wakeup(m
);
361 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
365 if (e
->enabled
&& !tv
) {
366 assert(e
->mainloop
->n_enabled_time_events
> 0);
367 e
->mainloop
->n_enabled_time_events
--;
368 } else if (!e
->enabled
&& tv
)
369 e
->mainloop
->n_enabled_time_events
++;
371 if ((e
->enabled
= !!tv
)) {
373 pa_mainloop_wakeup(e
->mainloop
);
376 if (e
->mainloop
->cached_next_time_event
&& e
->enabled
) {
377 assert(e
->mainloop
->cached_next_time_event
->enabled
);
379 if (pa_timeval_cmp(tv
, &e
->mainloop
->cached_next_time_event
->timeval
) < 0)
380 e
->mainloop
->cached_next_time_event
= e
;
381 } else if (e
->mainloop
->cached_next_time_event
== e
)
382 e
->mainloop
->cached_next_time_event
= NULL
;
385 static void mainloop_time_free(pa_time_event
*e
) {
390 e
->mainloop
->time_events_please_scan
++;
393 assert(e
->mainloop
->n_enabled_time_events
> 0);
394 e
->mainloop
->n_enabled_time_events
--;
397 if (e
->mainloop
->cached_next_time_event
== e
)
398 e
->mainloop
->cached_next_time_event
= NULL
;
400 /* no wakeup needed here. Think about it! */
403 static void mainloop_time_set_destroy(pa_time_event
*e
, pa_time_event_destroy_cb_t callback
) {
407 e
->destroy_callback
= callback
;
412 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
418 assert(a
== &m
->api
);
420 pa_mainloop_quit(m
, retval
);
423 static const pa_mainloop_api vtable
= {
426 .io_new
= mainloop_io_new
,
427 .io_enable
= mainloop_io_enable
,
428 .io_free
= mainloop_io_free
,
429 .io_set_destroy
= mainloop_io_set_destroy
,
431 .time_new
= mainloop_time_new
,
432 .time_restart
= mainloop_time_restart
,
433 .time_free
= mainloop_time_free
,
434 .time_set_destroy
= mainloop_time_set_destroy
,
436 .defer_new
= mainloop_defer_new
,
437 .defer_enable
= mainloop_defer_enable
,
438 .defer_free
= mainloop_defer_free
,
439 .defer_set_destroy
= mainloop_defer_set_destroy
,
441 .quit
= mainloop_quit
,
444 pa_mainloop
*pa_mainloop_new(void) {
447 m
= pa_xnew(pa_mainloop
, 1);
449 m
->wakeup_pipe_type
= 0;
450 if (pipe(m
->wakeup_pipe
) < 0) {
451 pa_log_error(__FILE__
": ERROR: cannot create wakeup pipe");
456 pa_make_nonblock_fd(m
->wakeup_pipe
[0]);
457 pa_make_nonblock_fd(m
->wakeup_pipe
[1]);
458 m
->wakeup_requested
= 0;
460 PA_LLIST_HEAD_INIT(pa_io_event
, m
->io_events
);
461 PA_LLIST_HEAD_INIT(pa_time_event
, m
->time_events
);
462 PA_LLIST_HEAD_INIT(pa_defer_event
, m
->defer_events
);
464 m
->n_enabled_defer_events
= m
->n_enabled_time_events
= m
->n_io_events
= 0;
465 m
->io_events_please_scan
= m
->time_events_please_scan
= m
->defer_events_please_scan
= 0;
467 m
->cached_next_time_event
= NULL
;
468 m
->prepared_timeout
= 0;
471 m
->max_pollfds
= m
->n_pollfds
= 0;
472 m
->rebuild_pollfds
= 1;
474 m
->quit
= m
->retval
= 0;
479 m
->state
= STATE_PASSIVE
;
482 m
->poll_func_userdata
= NULL
;
483 m
->poll_func_ret
= -1;
488 static void cleanup_io_events(pa_mainloop
*m
, int force
) {
493 pa_io_event
*n
= e
->next
;
495 if (!force
&& m
->io_events_please_scan
<= 0)
498 if (force
|| e
->dead
) {
499 PA_LLIST_REMOVE(pa_io_event
, m
->io_events
, e
);
502 assert(m
->io_events_please_scan
> 0);
503 m
->io_events_please_scan
--;
506 if (e
->destroy_callback
)
507 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
511 m
->rebuild_pollfds
= 1;
517 assert(m
->io_events_please_scan
== 0);
520 static void cleanup_time_events(pa_mainloop
*m
, int force
) {
525 pa_time_event
*n
= e
->next
;
527 if (!force
&& m
->time_events_please_scan
<= 0)
530 if (force
|| e
->dead
) {
531 PA_LLIST_REMOVE(pa_time_event
, m
->time_events
, e
);
534 assert(m
->time_events_please_scan
> 0);
535 m
->time_events_please_scan
--;
538 if (!e
->dead
&& e
->enabled
) {
539 assert(m
->n_enabled_time_events
> 0);
540 m
->n_enabled_time_events
--;
543 if (e
->destroy_callback
)
544 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
552 assert(m
->time_events_please_scan
== 0);
555 static void cleanup_defer_events(pa_mainloop
*m
, int force
) {
560 pa_defer_event
*n
= e
->next
;
562 if (!force
&& m
->defer_events_please_scan
<= 0)
565 if (force
|| e
->dead
) {
566 PA_LLIST_REMOVE(pa_defer_event
, m
->defer_events
, e
);
569 assert(m
->defer_events_please_scan
> 0);
570 m
->defer_events_please_scan
--;
573 if (!e
->dead
&& e
->enabled
) {
574 assert(m
->n_enabled_defer_events
> 0);
575 m
->n_enabled_defer_events
--;
578 if (e
->destroy_callback
)
579 e
->destroy_callback(&m
->api
, e
, e
->userdata
);
587 assert(m
->defer_events_please_scan
== 0);
591 void pa_mainloop_free(pa_mainloop
* m
) {
594 cleanup_io_events(m
, 1);
595 cleanup_defer_events(m
, 1);
596 cleanup_time_events(m
, 1);
598 pa_xfree(m
->pollfds
);
600 if (m
->wakeup_pipe
[0] >= 0)
601 close(m
->wakeup_pipe
[0]);
602 if (m
->wakeup_pipe
[1] >= 0)
603 close(m
->wakeup_pipe
[1]);
608 static void scan_dead(pa_mainloop
*m
) {
611 if (m
->io_events_please_scan
)
612 cleanup_io_events(m
, 0);
614 if (m
->time_events_please_scan
)
615 cleanup_time_events(m
, 0);
617 if (m
->defer_events_please_scan
)
618 cleanup_defer_events(m
, 0);
621 static void rebuild_pollfds(pa_mainloop
*m
) {
626 l
= m
->n_io_events
+ 1;
627 if (m
->max_pollfds
< l
) {
629 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
636 if (m
->wakeup_pipe
[0] >= 0) {
637 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
638 m
->pollfds
[0].events
= POLLIN
;
639 m
->pollfds
[0].revents
= 0;
644 for (e
= m
->io_events
; e
; e
= e
->next
) {
652 p
->events
= map_flags_to_libc(e
->events
);
659 m
->rebuild_pollfds
= 0;
662 static int dispatch_pollfds(pa_mainloop
*m
) {
666 assert(m
->poll_func_ret
> 0);
668 for (e
= m
->io_events
, k
= m
->poll_func_ret
; e
&& !m
->quit
&& k
> 0; e
= e
->next
) {
669 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
672 assert(e
->pollfd
->fd
== e
->fd
&& e
->callback
);
673 e
->callback(&m
->api
, e
, e
->fd
, map_flags_from_libc(e
->pollfd
->revents
), e
->userdata
);
674 e
->pollfd
->revents
= 0;
683 static int dispatch_defer(pa_mainloop
*m
) {
687 if (m
->n_enabled_defer_events
<= 0)
690 for (e
= m
->defer_events
; e
&& !m
->quit
; e
= e
->next
) {
691 if (e
->dead
|| !e
->enabled
)
695 e
->callback(&m
->api
, e
, e
->userdata
);
702 static pa_time_event
* find_next_time_event(pa_mainloop
*m
) {
703 pa_time_event
*t
, *n
= NULL
;
706 if (m
->cached_next_time_event
)
707 return m
->cached_next_time_event
;
709 for (t
= m
->time_events
; t
; t
= t
->next
) {
711 if (t
->dead
|| !t
->enabled
)
714 if (!n
|| pa_timeval_cmp(&t
->timeval
, &n
->timeval
) < 0) {
717 /* Shortcut for tv = { 0, 0 } */
718 if (n
->timeval
.tv_sec
<= 0)
723 m
->cached_next_time_event
= n
;
727 static int calc_next_timeout(pa_mainloop
*m
) {
732 if (!m
->n_enabled_time_events
)
735 t
= find_next_time_event(m
);
738 if (t
->timeval
.tv_sec
<= 0)
741 pa_gettimeofday(&now
);
743 if (pa_timeval_cmp(&t
->timeval
, &now
) <= 0)
746 usec
= pa_timeval_diff(&t
->timeval
, &now
);
747 return (int) (usec
/ 1000);
750 static int dispatch_timeout(pa_mainloop
*m
) {
756 if (m
->n_enabled_time_events
<= 0)
759 pa_gettimeofday(&now
);
761 for (e
= m
->time_events
; e
&& !m
->quit
; e
= e
->next
) {
763 if (e
->dead
|| !e
->enabled
)
766 if (pa_timeval_cmp(&e
->timeval
, &now
) <= 0) {
769 /* Disable time event */
770 mainloop_time_restart(e
, NULL
);
772 e
->callback(&m
->api
, e
, &e
->timeval
, e
->userdata
);
781 void pa_mainloop_wakeup(pa_mainloop
*m
) {
785 if (m
->wakeup_pipe
[1] >= 0 && m
->state
== STATE_POLLING
) {
786 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
787 m
->wakeup_requested
++;
791 static void clear_wakeup(pa_mainloop
*m
) {
796 if (m
->wakeup_pipe
[0] < 0)
799 if (m
->wakeup_requested
) {
800 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
));
801 m
->wakeup_requested
= 0;
805 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
807 assert(m
->state
== STATE_PASSIVE
);
815 if (m
->n_enabled_defer_events
<= 0) {
816 if (m
->rebuild_pollfds
)
819 m
->prepared_timeout
= calc_next_timeout(m
);
820 if (timeout
>= 0 && (timeout
< m
->prepared_timeout
|| m
->prepared_timeout
< 0))
821 m
->prepared_timeout
= timeout
;
824 m
->state
= STATE_PREPARED
;
828 m
->state
= STATE_QUIT
;
832 int pa_mainloop_poll(pa_mainloop
*m
) {
834 assert(m
->state
== STATE_PREPARED
);
839 m
->state
= STATE_POLLING
;
841 if (m
->n_enabled_defer_events
)
842 m
->poll_func_ret
= 0;
844 assert(!m
->rebuild_pollfds
);
847 m
->poll_func_ret
= m
->poll_func(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
, m
->poll_func_userdata
);
849 m
->poll_func_ret
= poll(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
);
851 if (m
->poll_func_ret
< 0) {
853 m
->poll_func_ret
= 0;
855 pa_log(__FILE__
": poll(): %s", pa_cstrerror(errno
));
859 m
->state
= m
->poll_func_ret
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
860 return m
->poll_func_ret
;
863 m
->state
= STATE_QUIT
;
867 int pa_mainloop_dispatch(pa_mainloop
*m
) {
871 assert(m
->state
== STATE_POLLED
);
876 if (m
->n_enabled_defer_events
)
877 dispatched
+= dispatch_defer(m
);
879 if (m
->n_enabled_time_events
)
880 dispatched
+= dispatch_timeout(m
);
885 if (m
->poll_func_ret
> 0)
886 dispatched
+= dispatch_pollfds(m
);
892 m
->state
= STATE_PASSIVE
;
897 m
->state
= STATE_QUIT
;
901 int pa_mainloop_get_retval(pa_mainloop
*m
) {
906 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
910 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
913 if ((r
= pa_mainloop_poll(m
)) < 0)
916 if ((r
= pa_mainloop_dispatch(m
)) < 0)
923 if ((r
== -2) && retval
)
924 *retval
= pa_mainloop_get_retval(m
);
928 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
931 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0);
941 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
946 pa_mainloop_wakeup(m
);
949 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
954 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
957 m
->poll_func
= poll_func
;
958 m
->poll_func_userdata
= userdata
;