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/idxset.h>
53 #include <pulsecore/log.h>
58 pa_mainloop
*mainloop
;
61 pa_io_event_flags_t events
;
62 void (*callback
) (pa_mainloop_api
*a
, pa_io_event
*e
, int fd
, pa_io_event_flags_t f
, void *userdata
);
63 struct pollfd
*pollfd
;
65 void (*destroy_callback
) (pa_mainloop_api
*a
, pa_io_event
*e
, void *userdata
);
68 struct pa_time_event
{
69 pa_mainloop
*mainloop
;
72 struct timeval timeval
;
73 void (*callback
)(pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
);
75 void (*destroy_callback
) (pa_mainloop_api
*a
, pa_time_event
*e
, void *userdata
);
78 struct pa_defer_event
{
79 pa_mainloop
*mainloop
;
82 void (*callback
)(pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
);
84 void (*destroy_callback
) (pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
);
88 pa_idxset
*io_events
, *time_events
, *defer_events
;
89 int io_events_scan_dead
, defer_events_scan_dead
, time_events_scan_dead
;
91 struct pollfd
*pollfds
;
92 unsigned max_pollfds
, n_pollfds
;
100 int deferred_pending
;
103 int wakeup_pipe_type
;
113 pa_poll_func poll_func
;
114 void *poll_func_userdata
;
118 static pa_io_event
* mainloop_io_new(
121 pa_io_event_flags_t events
,
122 void (*callback
) (pa_mainloop_api
*a
, pa_io_event
*e
, int fd
, pa_io_event_flags_t events
, void *userdata
),
128 assert(a
&& a
->userdata
&& fd
>= 0 && callback
);
130 assert(a
== &m
->api
);
132 e
= pa_xmalloc(sizeof(pa_io_event
));
138 e
->callback
= callback
;
139 e
->userdata
= userdata
;
140 e
->destroy_callback
= NULL
;
154 if ((select((SELECT_TYPE_ARG1
) fd
, NULL
, NULL
, SELECT_TYPE_ARG234
&xset
,
155 SELECT_TYPE_ARG5
&tv
) == -1) &&
156 (WSAGetLastError() == WSAENOTSOCK
)) {
157 pa_log_warn(__FILE__
": WARNING: cannot monitor non-socket file descriptors.");
163 pa_idxset_put(m
->io_events
, e
, NULL
);
164 m
->rebuild_pollfds
= 1;
166 pa_mainloop_wakeup(m
);
171 static void mainloop_io_enable(pa_io_event
*e
, pa_io_event_flags_t events
) {
172 assert(e
&& e
->mainloop
);
175 e
->mainloop
->rebuild_pollfds
= 1;
177 pa_mainloop_wakeup(e
->mainloop
);
180 static void mainloop_io_free(pa_io_event
*e
) {
181 assert(e
&& e
->mainloop
);
183 e
->dead
= e
->mainloop
->io_events_scan_dead
= e
->mainloop
->rebuild_pollfds
= 1;
185 pa_mainloop_wakeup(e
->mainloop
);
188 static void mainloop_io_set_destroy(pa_io_event
*e
, void (*callback
)(pa_mainloop_api
*a
, pa_io_event
*e
, void *userdata
)) {
190 e
->destroy_callback
= callback
;
194 static pa_defer_event
* mainloop_defer_new(pa_mainloop_api
*a
, void (*callback
) (pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
), void *userdata
) {
198 assert(a
&& a
->userdata
&& callback
);
200 assert(a
== &m
->api
);
202 e
= pa_xmalloc(sizeof(pa_defer_event
));
207 e
->callback
= callback
;
208 e
->userdata
= userdata
;
209 e
->destroy_callback
= NULL
;
211 pa_idxset_put(m
->defer_events
, e
, NULL
);
213 m
->deferred_pending
++;
215 pa_mainloop_wakeup(e
->mainloop
);
220 static void mainloop_defer_enable(pa_defer_event
*e
, int b
) {
223 if (e
->enabled
&& !b
) {
224 assert(e
->mainloop
->deferred_pending
> 0);
225 e
->mainloop
->deferred_pending
--;
226 } else if (!e
->enabled
&& b
) {
227 e
->mainloop
->deferred_pending
++;
228 pa_mainloop_wakeup(e
->mainloop
);
234 static void mainloop_defer_free(pa_defer_event
*e
) {
236 e
->dead
= e
->mainloop
->defer_events_scan_dead
= 1;
240 assert(e
->mainloop
->deferred_pending
> 0);
241 e
->mainloop
->deferred_pending
--;
245 static void mainloop_defer_set_destroy(pa_defer_event
*e
, void (*callback
)(pa_mainloop_api
*a
, pa_defer_event
*e
, void *userdata
)) {
247 e
->destroy_callback
= callback
;
251 static pa_time_event
* mainloop_time_new(pa_mainloop_api
*a
, const struct timeval
*tv
, void (*callback
) (pa_mainloop_api
*a
, pa_time_event
*e
, const struct timeval
*tv
, void *userdata
), void *userdata
) {
255 assert(a
&& a
->userdata
&& callback
);
257 assert(a
== &m
->api
);
259 e
= pa_xmalloc(sizeof(pa_time_event
));
267 e
->callback
= callback
;
268 e
->userdata
= userdata
;
269 e
->destroy_callback
= NULL
;
271 pa_idxset_put(m
->time_events
, e
, NULL
);
274 pa_mainloop_wakeup(m
);
279 static void mainloop_time_restart(pa_time_event
*e
, const struct timeval
*tv
) {
286 pa_mainloop_wakeup(e
->mainloop
);
291 static void mainloop_time_free(pa_time_event
*e
) {
294 e
->dead
= e
->mainloop
->time_events_scan_dead
= 1;
296 /* no wakeup needed here. Think about it! */
299 static void mainloop_time_set_destroy(pa_time_event
*e
, void (*callback
)(pa_mainloop_api
*a
, pa_time_event
*e
, void *userdata
)) {
301 e
->destroy_callback
= callback
;
306 static void mainloop_quit(pa_mainloop_api
*a
, int retval
) {
308 assert(a
&& a
->userdata
);
310 assert(a
== &m
->api
);
312 pa_mainloop_quit(m
, retval
);
315 static const pa_mainloop_api vtable
= {
318 .io_new
= mainloop_io_new
,
319 .io_enable
= mainloop_io_enable
,
320 .io_free
= mainloop_io_free
,
321 .io_set_destroy
= mainloop_io_set_destroy
,
323 .time_new
= mainloop_time_new
,
324 .time_restart
= mainloop_time_restart
,
325 .time_free
= mainloop_time_free
,
326 .time_set_destroy
= mainloop_time_set_destroy
,
328 .defer_new
= mainloop_defer_new
,
329 .defer_enable
= mainloop_defer_enable
,
330 .defer_free
= mainloop_defer_free
,
331 .defer_set_destroy
= mainloop_defer_set_destroy
,
333 .quit
= mainloop_quit
,
336 pa_mainloop
*pa_mainloop_new(void) {
339 m
= pa_xmalloc(sizeof(pa_mainloop
));
341 m
->wakeup_pipe_type
= 0;
342 if (pipe(m
->wakeup_pipe
) < 0) {
343 pa_log_error(__FILE__
": ERROR: cannot create wakeup pipe");
348 pa_make_nonblock_fd(m
->wakeup_pipe
[0]);
349 pa_make_nonblock_fd(m
->wakeup_pipe
[1]);
351 m
->io_events
= pa_idxset_new(NULL
, NULL
);
352 m
->defer_events
= pa_idxset_new(NULL
, NULL
);
353 m
->time_events
= pa_idxset_new(NULL
, NULL
);
355 assert(m
->io_events
&& m
->defer_events
&& m
->time_events
);
357 m
->io_events_scan_dead
= m
->defer_events_scan_dead
= m
->time_events_scan_dead
= 0;
360 m
->max_pollfds
= m
->n_pollfds
= 0;
361 m
->rebuild_pollfds
= 1;
363 m
->quit
= m
->retval
= 0;
368 m
->deferred_pending
= 0;
370 m
->state
= STATE_PASSIVE
;
373 m
->poll_func_userdata
= NULL
;
380 static int io_foreach(void *p
, uint32_t PA_GCC_UNUSED idx
, int *del
, void*userdata
) {
383 assert(e
&& del
&& all
);
385 if (!*all
&& !e
->dead
)
388 if (e
->destroy_callback
)
389 e
->destroy_callback(&e
->mainloop
->api
, e
, e
->userdata
);
395 static int time_foreach(void *p
, uint32_t PA_GCC_UNUSED idx
, int *del
, void*userdata
) {
396 pa_time_event
*e
= p
;
398 assert(e
&& del
&& all
);
400 if (!*all
&& !e
->dead
)
403 if (e
->destroy_callback
)
404 e
->destroy_callback(&e
->mainloop
->api
, e
, e
->userdata
);
410 static int defer_foreach(void *p
, PA_GCC_UNUSED
uint32_t idx
, int *del
, void*userdata
) {
411 pa_defer_event
*e
= p
;
413 assert(e
&& del
&& all
);
415 if (!*all
&& !e
->dead
)
418 if (e
->destroy_callback
)
419 e
->destroy_callback(&e
->mainloop
->api
, e
, e
->userdata
);
425 void pa_mainloop_free(pa_mainloop
* m
) {
429 pa_idxset_foreach(m
->io_events
, io_foreach
, &all
);
430 pa_idxset_foreach(m
->time_events
, time_foreach
, &all
);
431 pa_idxset_foreach(m
->defer_events
, defer_foreach
, &all
);
433 pa_idxset_free(m
->io_events
, NULL
, NULL
);
434 pa_idxset_free(m
->time_events
, NULL
, NULL
);
435 pa_idxset_free(m
->defer_events
, NULL
, NULL
);
437 pa_xfree(m
->pollfds
);
439 if (m
->wakeup_pipe
[0] >= 0)
440 close(m
->wakeup_pipe
[0]);
441 if (m
->wakeup_pipe
[1] >= 0)
442 close(m
->wakeup_pipe
[1]);
447 static void scan_dead(pa_mainloop
*m
) {
451 if (m
->io_events_scan_dead
)
452 pa_idxset_foreach(m
->io_events
, io_foreach
, &all
);
453 if (m
->time_events_scan_dead
)
454 pa_idxset_foreach(m
->time_events
, time_foreach
, &all
);
455 if (m
->defer_events_scan_dead
)
456 pa_idxset_foreach(m
->defer_events
, defer_foreach
, &all
);
458 m
->io_events_scan_dead
= m
->time_events_scan_dead
= m
->defer_events_scan_dead
= 0;
461 static void rebuild_pollfds(pa_mainloop
*m
) {
464 uint32_t idx
= PA_IDXSET_INVALID
;
467 l
= pa_idxset_size(m
->io_events
) + 1;
468 if (m
->max_pollfds
< l
) {
469 m
->pollfds
= pa_xrealloc(m
->pollfds
, sizeof(struct pollfd
)*l
);
476 if (m
->wakeup_pipe
[0] >= 0) {
477 m
->pollfds
[0].fd
= m
->wakeup_pipe
[0];
478 m
->pollfds
[0].events
= POLLIN
;
479 m
->pollfds
[0].revents
= 0;
484 for (e
= pa_idxset_first(m
->io_events
, &idx
); e
; e
= pa_idxset_next(m
->io_events
, &idx
)) {
493 ((e
->events
& PA_IO_EVENT_INPUT
) ? POLLIN
: 0) |
494 ((e
->events
& PA_IO_EVENT_OUTPUT
) ? POLLOUT
: 0) |
503 m
->rebuild_pollfds
= 0;
506 static int dispatch_pollfds(pa_mainloop
*m
) {
507 uint32_t idx
= PA_IDXSET_INVALID
;
511 for (e
= pa_idxset_first(m
->io_events
, &idx
); e
&& !m
->quit
; e
= pa_idxset_next(m
->io_events
, &idx
)) {
512 if (e
->dead
|| !e
->pollfd
|| !e
->pollfd
->revents
)
515 assert(e
->pollfd
->fd
== e
->fd
&& e
->callback
);
516 e
->callback(&m
->api
, e
, e
->fd
,
517 (e
->pollfd
->revents
& POLLHUP
? PA_IO_EVENT_HANGUP
: 0) |
518 (e
->pollfd
->revents
& POLLIN
? PA_IO_EVENT_INPUT
: 0) |
519 (e
->pollfd
->revents
& POLLOUT
? PA_IO_EVENT_OUTPUT
: 0) |
520 (e
->pollfd
->revents
& POLLERR
? PA_IO_EVENT_ERROR
: 0),
522 e
->pollfd
->revents
= 0;
529 static int dispatch_defer(pa_mainloop
*m
) {
534 if (!m
->deferred_pending
)
537 for (e
= pa_idxset_first(m
->defer_events
, &idx
); e
&& !m
->quit
; e
= pa_idxset_next(m
->defer_events
, &idx
)) {
538 if (e
->dead
|| !e
->enabled
)
542 e
->callback(&m
->api
, e
, e
->userdata
);
549 static int calc_next_timeout(pa_mainloop
*m
) {
556 if (pa_idxset_isempty(m
->time_events
))
559 for (e
= pa_idxset_first(m
->time_events
, &idx
); e
; e
= pa_idxset_next(m
->time_events
, &idx
)) {
562 if (e
->dead
|| !e
->enabled
)
565 /* Let's save a system call */
567 pa_gettimeofday(&now
);
571 if (e
->timeval
.tv_sec
< now
.tv_sec
|| (e
->timeval
.tv_sec
== now
.tv_sec
&& e
->timeval
.tv_usec
<= now
.tv_usec
))
574 tmp
= (e
->timeval
.tv_sec
- now
.tv_sec
)*1000;
576 if (e
->timeval
.tv_usec
> now
.tv_usec
)
577 tmp
+= (e
->timeval
.tv_usec
- now
.tv_usec
)/1000;
579 tmp
-= (now
.tv_usec
- e
->timeval
.tv_usec
)/1000;
583 else if (t
== -1 || tmp
< t
)
590 static int dispatch_timeout(pa_mainloop
*m
) {
598 if (pa_idxset_isempty(m
->time_events
))
601 for (e
= pa_idxset_first(m
->time_events
, &idx
); e
&& !m
->quit
; e
= pa_idxset_next(m
->time_events
, &idx
)) {
603 if (e
->dead
|| !e
->enabled
)
606 /* Let's save a system call */
608 pa_gettimeofday(&now
);
612 if (e
->timeval
.tv_sec
< now
.tv_sec
|| (e
->timeval
.tv_sec
== now
.tv_sec
&& e
->timeval
.tv_usec
<= now
.tv_usec
)) {
616 e
->callback(&m
->api
, e
, &e
->timeval
, e
->userdata
);
625 void pa_mainloop_wakeup(pa_mainloop
*m
) {
629 if (m
->wakeup_pipe
[1] >= 0)
630 pa_write(m
->wakeup_pipe
[1], &c
, sizeof(c
), &m
->wakeup_pipe_type
);
633 static void clear_wakeup(pa_mainloop
*m
) {
638 if (m
->wakeup_pipe
[0] < 0)
641 while (pa_read(m
->wakeup_pipe
[0], &c
, sizeof(c
), &m
->wakeup_pipe_type
) == sizeof(c
));
644 int pa_mainloop_prepare(pa_mainloop
*m
, int timeout
) {
646 assert(m
->state
== STATE_PASSIVE
);
654 if (!m
->deferred_pending
) {
656 if (m
->rebuild_pollfds
)
659 m
->prepared_timeout
= calc_next_timeout(m
);
660 if (timeout
>= 0 && (timeout
< m
->prepared_timeout
|| m
->prepared_timeout
< 0))
661 m
->prepared_timeout
= timeout
;
664 m
->state
= STATE_PREPARED
;
668 m
->state
= STATE_QUIT
;
672 int pa_mainloop_poll(pa_mainloop
*m
) {
676 assert(m
->state
== STATE_PREPARED
);
681 m
->state
= STATE_POLLING
;
683 if (m
->deferred_pending
)
687 r
= m
->poll_func(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
, m
->poll_func_userdata
);
689 r
= poll(m
->pollfds
, m
->n_pollfds
, m
->prepared_timeout
);
695 pa_log(__FILE__
": poll(): %s", pa_cstrerror(errno
));
699 m
->state
= r
< 0 ? STATE_PASSIVE
: STATE_POLLED
;
703 m
->state
= STATE_QUIT
;
707 int pa_mainloop_dispatch(pa_mainloop
*m
) {
711 assert(m
->state
== STATE_POLLED
);
716 if (m
->deferred_pending
)
717 dispatched
+= dispatch_defer(m
);
719 dispatched
+= dispatch_timeout(m
);
724 dispatched
+= dispatch_pollfds(m
);
731 m
->state
= STATE_PASSIVE
;
736 m
->state
= STATE_QUIT
;
740 int pa_mainloop_get_retval(pa_mainloop
*m
) {
745 int pa_mainloop_iterate(pa_mainloop
*m
, int block
, int *retval
) {
749 if ((r
= pa_mainloop_prepare(m
, block
? -1 : 0)) < 0)
752 if ((r
= pa_mainloop_poll(m
)) < 0)
755 if ((r
= pa_mainloop_dispatch(m
)) < 0)
762 if ((r
== -2) && retval
)
763 *retval
= pa_mainloop_get_retval(m
);
767 int pa_mainloop_run(pa_mainloop
*m
, int *retval
) {
770 while ((r
= pa_mainloop_iterate(m
, 1, retval
)) >= 0);
780 void pa_mainloop_quit(pa_mainloop
*m
, int retval
) {
785 pa_mainloop_wakeup(m
);
788 pa_mainloop_api
* pa_mainloop_get_api(pa_mainloop
*m
) {
793 void pa_mainloop_set_poll_func(pa_mainloop
*m
, pa_poll_func poll_func
, void *userdata
) {
796 m
->poll_func
= poll_func
;
797 m
->poll_func_userdata
= userdata
;
802 void pa_mainloop_dump(pa_mainloop
*m
) {
805 pa_log(__FILE__
": Dumping mainloop sources START");
808 uint32_t idx
= PA_IDXSET_INVALID
;
810 for (e
= pa_idxset_first(m
->io_events
, &idx
); e
; e
= pa_idxset_next(m
->io_events
, &idx
)) {
814 pa_log(__FILE__
": kind=io fd=%i events=%i callback=%p userdata=%p", e
->fd
, (int) e
->events
, (void*) e
->callback
, (void*) e
->userdata
);
818 uint32_t idx
= PA_IDXSET_INVALID
;
820 for (e
= pa_idxset_first(m
->defer_events
, &idx
); e
; e
= pa_idxset_next(m
->defer_events
, &idx
)) {
824 pa_log(__FILE__
": kind=defer enabled=%i callback=%p userdata=%p", e
->enabled
, (void*) e
->callback
, (void*) e
->userdata
);
828 uint32_t idx
= PA_IDXSET_INVALID
;
830 for (e
= pa_idxset_first(m
->time_events
, &idx
); e
; e
= pa_idxset_next(m
->time_events
, &idx
)) {
834 pa_log(__FILE__
": kind=time enabled=%i time=%lu.%lu callback=%p userdata=%p", e
->enabled
, (unsigned long) e
->timeval
.tv_sec
, (unsigned long) e
->timeval
.tv_usec
, (void*) e
->callback
, (void*) e
->userdata
);
838 pa_log(__FILE__
": Dumping mainloop sources STOP");