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
9 published by the Free Software Foundation; either version 2.1 of the
10 License, 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 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with PulseAudio; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
27 #include <sys/types.h>
34 #include <sys/utsname.h>
40 #include <pulsecore/poll.h>
43 #include <pulse/xmalloc.h>
44 #include <pulse/timeval.h>
46 #include <pulsecore/core-error.h>
47 #include <pulsecore/rtclock.h>
48 #include <pulsecore/macro.h>
49 #include <pulsecore/llist.h>
50 #include <pulsecore/rtsig.h>
51 #include <pulsecore/flist.h>
52 #include <pulsecore/core-util.h>
53 #include <pulsecore/winsock.h>
54 #include <pulsecore/ratelimit.h>
58 /* #define DEBUG_TIMING */
61 struct pollfd
*pollfd
, *pollfd2
;
62 unsigned n_pollfd_alloc
, n_pollfd_used
;
64 struct timeval next_elapse
;
65 pa_bool_t timer_enabled
:1;
67 pa_bool_t scan_for_dead
:1;
69 pa_bool_t installed
:1;
70 pa_bool_t rebuild_needed
:1;
74 pa_bool_t timer_armed
:1;
76 pa_bool_t dont_use_ppoll
:1;
79 sigset_t sigset_unblocked
;
85 pa_usec_t slept
, awake
;
88 PA_LLIST_HEAD(pa_rtpoll_item
, items
);
91 struct pa_rtpoll_item
{
95 pa_rtpoll_priority_t priority
;
97 struct pollfd
*pollfd
;
100 int (*work_cb
)(pa_rtpoll_item
*i
);
101 int (*before_cb
)(pa_rtpoll_item
*i
);
102 void (*after_cb
)(pa_rtpoll_item
*i
);
105 PA_LLIST_FIELDS(pa_rtpoll_item
);
108 PA_STATIC_FLIST_DECLARE(items
, 0, pa_xfree
);
110 static void signal_handler_noop(int s
) { /* write(2, "signal\n", 7); */ }
112 pa_rtpoll
*pa_rtpoll_new(void) {
115 p
= pa_xnew(pa_rtpoll
, 1);
120 /* ppoll is broken on Linux < 2.6.16 */
121 p
->dont_use_ppoll
= FALSE
;
125 unsigned major
, minor
, micro
;
127 pa_assert_se(uname(&u
) == 0);
129 if (sscanf(u
.release
, "%u.%u.%u", &major
, &minor
, µ
) != 3 ||
131 (major
== 2 && minor
< 6) ||
132 (major
== 2 && minor
== 6 && micro
< 16))
134 p
->dont_use_ppoll
= TRUE
;
140 sigemptyset(&p
->sigset_unblocked
);
141 p
->timer
= (timer_t
) -1;
142 p
->timer_armed
= FALSE
;
146 p
->n_pollfd_alloc
= 32;
147 p
->pollfd
= pa_xnew(struct pollfd
, p
->n_pollfd_alloc
);
148 p
->pollfd2
= pa_xnew(struct pollfd
, p
->n_pollfd_alloc
);
149 p
->n_pollfd_used
= 0;
151 memset(&p
->next_elapse
, 0, sizeof(p
->next_elapse
));
152 p
->timer_enabled
= FALSE
;
155 p
->installed
= FALSE
;
156 p
->scan_for_dead
= FALSE
;
157 p
->rebuild_needed
= FALSE
;
160 PA_LLIST_HEAD_INIT(pa_rtpoll_item
, p
->items
);
163 p
->timestamp
= pa_rtclock_usec();
164 p
->slept
= p
->awake
= 0;
170 void pa_rtpoll_install(pa_rtpoll
*p
) {
172 pa_assert(!p
->installed
);
178 if (p
->dont_use_ppoll
)
182 if ((p
->rtsig
= pa_rtsig_get_for_thread()) < 0) {
183 pa_log_warn("Failed to reserve POSIX realtime signal.");
187 pa_log_debug("Acquired POSIX realtime signal %s", pa_sig2str(p
->rtsig
));
193 pa_assert_se(sigemptyset(&ss
) == 0);
194 pa_assert_se(sigaddset(&ss
, p
->rtsig
) == 0);
195 pa_assert_se(pthread_sigmask(SIG_BLOCK
, &ss
, &p
->sigset_unblocked
) == 0);
196 pa_assert_se(sigdelset(&p
->sigset_unblocked
, p
->rtsig
) == 0);
198 memset(&sa
, 0, sizeof(sa
));
199 sa
.sa_handler
= signal_handler_noop
;
200 pa_assert_se(sigemptyset(&sa
.sa_mask
) == 0);
202 pa_assert_se(sigaction(p
->rtsig
, &sa
, NULL
) == 0);
204 /* We never reset the signal handler. Why should we? */
210 static void rtpoll_rebuild(pa_rtpoll
*p
) {
212 struct pollfd
*e
, *t
;
218 p
->rebuild_needed
= FALSE
;
220 if (p
->n_pollfd_used
> p
->n_pollfd_alloc
) {
221 /* Hmm, we have to allocate some more space */
222 p
->n_pollfd_alloc
= p
->n_pollfd_used
* 2;
223 p
->pollfd2
= pa_xrealloc(p
->pollfd2
, p
->n_pollfd_alloc
* sizeof(struct pollfd
));
229 for (i
= p
->items
; i
; i
= i
->next
) {
231 if (i
->n_pollfd
> 0) {
232 size_t l
= i
->n_pollfd
* sizeof(struct pollfd
);
235 memcpy(e
, i
->pollfd
, l
);
246 pa_assert((unsigned) (e
- p
->pollfd2
) == p
->n_pollfd_used
);
248 p
->pollfd
= p
->pollfd2
;
252 p
->pollfd2
= pa_xrealloc(p
->pollfd2
, p
->n_pollfd_alloc
* sizeof(struct pollfd
));
256 static void rtpoll_item_destroy(pa_rtpoll_item
*i
) {
263 PA_LLIST_REMOVE(pa_rtpoll_item
, p
->items
, i
);
265 p
->n_pollfd_used
-= i
->n_pollfd
;
267 if (pa_flist_push(PA_STATIC_FLIST_GET(items
), i
) < 0)
270 p
->rebuild_needed
= TRUE
;
273 void pa_rtpoll_free(pa_rtpoll
*p
) {
277 rtpoll_item_destroy(p
->items
);
280 pa_xfree(p
->pollfd2
);
283 if (p
->timer
!= (timer_t
) -1)
284 timer_delete(p
->timer
);
290 static void reset_revents(pa_rtpoll_item
*i
) {
296 if (!(f
= pa_rtpoll_item_get_pollfd(i
, &n
)))
303 static void reset_all_revents(pa_rtpoll
*p
) {
308 for (i
= p
->items
; i
; i
= i
->next
) {
317 int pa_rtpoll_run(pa_rtpoll
*p
, pa_bool_t wait
) {
320 struct timeval timeout
;
323 pa_assert(!p
->running
);
324 pa_assert(p
->installed
);
328 /* First, let's do some work */
329 for (i
= p
->items
; i
&& i
->priority
< PA_RTPOLL_NEVER
; i
= i
->next
) {
341 if ((k
= i
->work_cb(i
)) != 0) {
349 /* Now let's prepare for entering the sleep */
350 for (i
= p
->items
; i
&& i
->priority
< PA_RTPOLL_NEVER
; i
= i
->next
) {
359 if (p
->quit
|| (k
= i
->before_cb(i
)) != 0) {
361 /* Hmm, this one doesn't let us enter the poll, so rewind everything */
363 for (i
= i
->prev
; i
; i
= i
->prev
) {
381 if (p
->rebuild_needed
)
384 memset(&timeout
, 0, sizeof(timeout
));
386 /* Calculate timeout */
387 if (wait
&& !p
->quit
&& p
->timer_enabled
) {
389 pa_rtclock_get(&now
);
391 if (pa_timeval_cmp(&p
->next_elapse
, &now
) > 0)
392 pa_timeval_add(&timeout
, pa_timeval_diff(&p
->next_elapse
, &now
));
397 pa_usec_t now
= pa_rtclock_usec();
398 p
->awake
= now
- p
->timestamp
;
403 /* OK, now let's sleep */
407 if (!p
->dont_use_ppoll
)
411 ts
.tv_sec
= timeout
.tv_sec
;
412 ts
.tv_nsec
= timeout
.tv_usec
* 1000;
413 r
= ppoll(p
->pollfd
, p
->n_pollfd_used
, (!wait
|| p
->quit
|| p
->timer_enabled
) ? &ts
: NULL
, p
->rtsig
< 0 ? NULL
: &p
->sigset_unblocked
);
420 r
= poll(p
->pollfd
, p
->n_pollfd_used
, (!wait
|| p
->quit
|| p
->timer_enabled
) ? (int) ((timeout
.tv_sec
*1000) + (timeout
.tv_usec
/ 1000)) : -1);
424 pa_usec_t now
= pa_rtclock_usec();
425 p
->slept
= now
- p
->timestamp
;
428 pa_log("Process time %llu ms; sleep time %llu ms",
429 (unsigned long long) (p
->awake
/ PA_USEC_PER_MSEC
),
430 (unsigned long long) (p
->slept
/ PA_USEC_PER_MSEC
));
435 if (errno
== EAGAIN
|| errno
== EINTR
)
438 pa_log_error("poll(): %s", pa_cstrerror(errno
));
440 reset_all_revents(p
);
443 /* Let's tell everyone that we left the sleep */
444 for (i
= p
->items
; i
&& i
->priority
< PA_RTPOLL_NEVER
; i
= i
->next
) {
459 if (p
->scan_for_dead
) {
462 p
->scan_for_dead
= FALSE
;
464 for (i
= p
->items
; i
; i
= n
) {
468 rtpoll_item_destroy(i
);
472 return r
< 0 ? r
: !p
->quit
;
475 static void update_timer(pa_rtpoll
*p
) {
481 if (!p
->dont_use_ppoll
) {
484 if (p
->timer
== (timer_t
) -1) {
487 memset(&se
, 0, sizeof(se
));
488 se
.sigev_notify
= SIGEV_SIGNAL
;
489 se
.sigev_signo
= p
->rtsig
;
491 if (timer_create(CLOCK_MONOTONIC
, &se
, &p
->timer
) < 0)
492 if (timer_create(CLOCK_REALTIME
, &se
, &p
->timer
) < 0) {
493 pa_log_warn("Failed to allocate POSIX timer: %s", pa_cstrerror(errno
));
494 p
->timer
= (timer_t
) -1;
498 if (p
->timer
!= (timer_t
) -1) {
499 struct itimerspec its
;
500 struct timespec ts
= { .tv_sec
= 0, .tv_nsec
= 0 };
503 if (p
->timer_armed
) {
504 /* First disarm timer */
505 memset(&its
, 0, sizeof(its
));
506 pa_assert_se(timer_settime(p
->timer
, TIMER_ABSTIME
, &its
, NULL
) == 0);
508 /* Remove a signal that might be waiting in the signal q */
509 pa_assert_se(sigemptyset(&ss
) == 0);
510 pa_assert_se(sigaddset(&ss
, p
->rtsig
) == 0);
511 sigtimedwait(&ss
, NULL
, &ts
);
514 /* And install the new timer */
515 if (p
->timer_enabled
) {
516 memset(&its
, 0, sizeof(its
));
518 its
.it_value
.tv_sec
= p
->next_elapse
.tv_sec
;
519 its
.it_value
.tv_nsec
= p
->next_elapse
.tv_usec
*1000;
521 /* Make sure that 0,0 is not understood as
523 if (its
.it_value
.tv_sec
== 0 && its
.it_value
.tv_nsec
== 0)
524 its
.it_value
.tv_nsec
= 1;
525 pa_assert_se(timer_settime(p
->timer
, TIMER_ABSTIME
, &its
, NULL
) == 0);
528 p
->timer_armed
= p
->timer_enabled
;
538 void pa_rtpoll_set_timer_absolute(pa_rtpoll
*p
, pa_usec_t usec
) {
541 pa_timeval_store(&p
->next_elapse
, usec
);
542 p
->timer_enabled
= TRUE
;
547 void pa_rtpoll_set_timer_relative(pa_rtpoll
*p
, pa_usec_t usec
) {
550 /* Scheduling a timeout for more than an hour is very very suspicious */
551 pa_assert(usec
<= PA_USEC_PER_SEC
*60ULL*60ULL);
553 pa_rtclock_get(&p
->next_elapse
);
554 pa_timeval_add(&p
->next_elapse
, usec
);
555 p
->timer_enabled
= TRUE
;
560 void pa_rtpoll_set_timer_disabled(pa_rtpoll
*p
) {
563 memset(&p
->next_elapse
, 0, sizeof(p
->next_elapse
));
564 p
->timer_enabled
= FALSE
;
569 pa_rtpoll_item
*pa_rtpoll_item_new(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, unsigned n_fds
) {
570 pa_rtpoll_item
*i
, *j
, *l
= NULL
;
574 if (!(i
= pa_flist_pop(PA_STATIC_FLIST_GET(items
))))
575 i
= pa_xnew(pa_rtpoll_item
, 1);
588 for (j
= p
->items
; j
; j
= j
->next
) {
589 if (prio
<= j
->priority
)
595 PA_LLIST_INSERT_AFTER(pa_rtpoll_item
, p
->items
, j
? j
->prev
: l
, i
);
598 p
->rebuild_needed
= 1;
599 p
->n_pollfd_used
+= n_fds
;
605 void pa_rtpoll_item_free(pa_rtpoll_item
*i
) {
608 if (i
->rtpoll
->running
) {
610 i
->rtpoll
->scan_for_dead
= TRUE
;
614 rtpoll_item_destroy(i
);
617 struct pollfd
*pa_rtpoll_item_get_pollfd(pa_rtpoll_item
*i
, unsigned *n_fds
) {
621 if (i
->rtpoll
->rebuild_needed
)
622 rtpoll_rebuild(i
->rtpoll
);
625 *n_fds
= i
->n_pollfd
;
630 void pa_rtpoll_item_set_before_callback(pa_rtpoll_item
*i
, int (*before_cb
)(pa_rtpoll_item
*i
)) {
632 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
634 i
->before_cb
= before_cb
;
637 void pa_rtpoll_item_set_after_callback(pa_rtpoll_item
*i
, void (*after_cb
)(pa_rtpoll_item
*i
)) {
639 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
641 i
->after_cb
= after_cb
;
644 void pa_rtpoll_item_set_work_callback(pa_rtpoll_item
*i
, int (*work_cb
)(pa_rtpoll_item
*i
)) {
646 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
648 i
->work_cb
= work_cb
;
651 void pa_rtpoll_item_set_userdata(pa_rtpoll_item
*i
, void *userdata
) {
654 i
->userdata
= userdata
;
657 void* pa_rtpoll_item_get_userdata(pa_rtpoll_item
*i
) {
663 static int fdsem_before(pa_rtpoll_item
*i
) {
665 if (pa_fdsem_before_poll(i
->userdata
) < 0)
666 return 1; /* 1 means immediate restart of the loop */
671 static void fdsem_after(pa_rtpoll_item
*i
) {
674 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
675 pa_fdsem_after_poll(i
->userdata
);
678 pa_rtpoll_item
*pa_rtpoll_item_new_fdsem(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_fdsem
*f
) {
680 struct pollfd
*pollfd
;
685 i
= pa_rtpoll_item_new(p
, prio
, 1);
687 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
689 pollfd
->fd
= pa_fdsem_get(f
);
690 pollfd
->events
= POLLIN
;
692 i
->before_cb
= fdsem_before
;
693 i
->after_cb
= fdsem_after
;
699 static int asyncmsgq_read_before(pa_rtpoll_item
*i
) {
702 if (pa_asyncmsgq_read_before_poll(i
->userdata
) < 0)
703 return 1; /* 1 means immediate restart of the loop */
708 static void asyncmsgq_read_after(pa_rtpoll_item
*i
) {
711 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
712 pa_asyncmsgq_read_after_poll(i
->userdata
);
715 static int asyncmsgq_read_work(pa_rtpoll_item
*i
) {
716 pa_msgobject
*object
;
724 if (pa_asyncmsgq_get(i
->userdata
, &object
, &code
, &data
, &offset
, &chunk
, 0) == 0) {
727 if (!object
&& code
== PA_MESSAGE_SHUTDOWN
) {
728 pa_asyncmsgq_done(i
->userdata
, 0);
729 pa_rtpoll_quit(i
->rtpoll
);
733 ret
= pa_asyncmsgq_dispatch(object
, code
, data
, offset
, &chunk
);
734 pa_asyncmsgq_done(i
->userdata
, ret
);
741 pa_rtpoll_item
*pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_asyncmsgq
*q
) {
743 struct pollfd
*pollfd
;
748 i
= pa_rtpoll_item_new(p
, prio
, 1);
750 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
751 pollfd
->fd
= pa_asyncmsgq_read_fd(q
);
752 pollfd
->events
= POLLIN
;
754 i
->before_cb
= asyncmsgq_read_before
;
755 i
->after_cb
= asyncmsgq_read_after
;
756 i
->work_cb
= asyncmsgq_read_work
;
762 static int asyncmsgq_write_before(pa_rtpoll_item
*i
) {
765 pa_asyncmsgq_write_before_poll(i
->userdata
);
769 static void asyncmsgq_write_after(pa_rtpoll_item
*i
) {
772 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
773 pa_asyncmsgq_write_after_poll(i
->userdata
);
776 pa_rtpoll_item
*pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_asyncmsgq
*q
) {
778 struct pollfd
*pollfd
;
783 i
= pa_rtpoll_item_new(p
, prio
, 1);
785 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
786 pollfd
->fd
= pa_asyncmsgq_write_fd(q
);
787 pollfd
->events
= POLLIN
;
789 i
->before_cb
= asyncmsgq_write_before
;
790 i
->after_cb
= asyncmsgq_write_after
;
797 void pa_rtpoll_quit(pa_rtpoll
*p
) {