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_now();
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_now();
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_now();
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
)
485 if (p
->timer
== (timer_t
) -1) {
488 memset(&se
, 0, sizeof(se
));
489 se
.sigev_notify
= SIGEV_SIGNAL
;
490 se
.sigev_signo
= p
->rtsig
;
492 if (timer_create(CLOCK_MONOTONIC
, &se
, &p
->timer
) < 0)
493 if (timer_create(CLOCK_REALTIME
, &se
, &p
->timer
) < 0) {
494 pa_log_warn("Failed to allocate POSIX timer: %s", pa_cstrerror(errno
));
495 p
->timer
= (timer_t
) -1;
499 if (p
->timer
!= (timer_t
) -1) {
500 struct itimerspec its
;
501 struct timespec ts
= { .tv_sec
= 0, .tv_nsec
= 0 };
504 if (p
->timer_armed
) {
505 /* First disarm timer */
506 memset(&its
, 0, sizeof(its
));
507 pa_assert_se(timer_settime(p
->timer
, TIMER_ABSTIME
, &its
, NULL
) == 0);
509 /* Remove a signal that might be waiting in the signal q */
510 pa_assert_se(sigemptyset(&ss
) == 0);
511 pa_assert_se(sigaddset(&ss
, p
->rtsig
) == 0);
512 sigtimedwait(&ss
, NULL
, &ts
);
515 /* And install the new timer */
516 if (p
->timer_enabled
) {
517 memset(&its
, 0, sizeof(its
));
519 its
.it_value
.tv_sec
= p
->next_elapse
.tv_sec
;
520 its
.it_value
.tv_nsec
= p
->next_elapse
.tv_usec
*1000;
522 /* Make sure that 0,0 is not understood as
524 if (its
.it_value
.tv_sec
== 0 && its
.it_value
.tv_nsec
== 0)
525 its
.it_value
.tv_nsec
= 1;
526 pa_assert_se(timer_settime(p
->timer
, TIMER_ABSTIME
, &its
, NULL
) == 0);
529 p
->timer_armed
= p
->timer_enabled
;
535 void pa_rtpoll_set_timer_absolute(pa_rtpoll
*p
, pa_usec_t usec
) {
538 pa_timeval_store(&p
->next_elapse
, usec
);
539 p
->timer_enabled
= TRUE
;
544 void pa_rtpoll_set_timer_relative(pa_rtpoll
*p
, pa_usec_t usec
) {
547 /* Scheduling a timeout for more than an hour is very very suspicious */
548 pa_assert(usec
<= PA_USEC_PER_SEC
*60ULL*60ULL);
550 pa_rtclock_get(&p
->next_elapse
);
551 pa_timeval_add(&p
->next_elapse
, usec
);
552 p
->timer_enabled
= TRUE
;
557 void pa_rtpoll_set_timer_disabled(pa_rtpoll
*p
) {
560 memset(&p
->next_elapse
, 0, sizeof(p
->next_elapse
));
561 p
->timer_enabled
= FALSE
;
566 pa_rtpoll_item
*pa_rtpoll_item_new(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, unsigned n_fds
) {
567 pa_rtpoll_item
*i
, *j
, *l
= NULL
;
571 if (!(i
= pa_flist_pop(PA_STATIC_FLIST_GET(items
))))
572 i
= pa_xnew(pa_rtpoll_item
, 1);
585 for (j
= p
->items
; j
; j
= j
->next
) {
586 if (prio
<= j
->priority
)
592 PA_LLIST_INSERT_AFTER(pa_rtpoll_item
, p
->items
, j
? j
->prev
: l
, i
);
595 p
->rebuild_needed
= 1;
596 p
->n_pollfd_used
+= n_fds
;
602 void pa_rtpoll_item_free(pa_rtpoll_item
*i
) {
605 if (i
->rtpoll
->running
) {
607 i
->rtpoll
->scan_for_dead
= TRUE
;
611 rtpoll_item_destroy(i
);
614 struct pollfd
*pa_rtpoll_item_get_pollfd(pa_rtpoll_item
*i
, unsigned *n_fds
) {
618 if (i
->rtpoll
->rebuild_needed
)
619 rtpoll_rebuild(i
->rtpoll
);
622 *n_fds
= i
->n_pollfd
;
627 void pa_rtpoll_item_set_before_callback(pa_rtpoll_item
*i
, int (*before_cb
)(pa_rtpoll_item
*i
)) {
629 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
631 i
->before_cb
= before_cb
;
634 void pa_rtpoll_item_set_after_callback(pa_rtpoll_item
*i
, void (*after_cb
)(pa_rtpoll_item
*i
)) {
636 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
638 i
->after_cb
= after_cb
;
641 void pa_rtpoll_item_set_work_callback(pa_rtpoll_item
*i
, int (*work_cb
)(pa_rtpoll_item
*i
)) {
643 pa_assert(i
->priority
< PA_RTPOLL_NEVER
);
645 i
->work_cb
= work_cb
;
648 void pa_rtpoll_item_set_userdata(pa_rtpoll_item
*i
, void *userdata
) {
651 i
->userdata
= userdata
;
654 void* pa_rtpoll_item_get_userdata(pa_rtpoll_item
*i
) {
660 static int fdsem_before(pa_rtpoll_item
*i
) {
662 if (pa_fdsem_before_poll(i
->userdata
) < 0)
663 return 1; /* 1 means immediate restart of the loop */
668 static void fdsem_after(pa_rtpoll_item
*i
) {
671 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
672 pa_fdsem_after_poll(i
->userdata
);
675 pa_rtpoll_item
*pa_rtpoll_item_new_fdsem(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_fdsem
*f
) {
677 struct pollfd
*pollfd
;
682 i
= pa_rtpoll_item_new(p
, prio
, 1);
684 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
686 pollfd
->fd
= pa_fdsem_get(f
);
687 pollfd
->events
= POLLIN
;
689 i
->before_cb
= fdsem_before
;
690 i
->after_cb
= fdsem_after
;
696 static int asyncmsgq_read_before(pa_rtpoll_item
*i
) {
699 if (pa_asyncmsgq_read_before_poll(i
->userdata
) < 0)
700 return 1; /* 1 means immediate restart of the loop */
705 static void asyncmsgq_read_after(pa_rtpoll_item
*i
) {
708 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
709 pa_asyncmsgq_read_after_poll(i
->userdata
);
712 static int asyncmsgq_read_work(pa_rtpoll_item
*i
) {
713 pa_msgobject
*object
;
721 if (pa_asyncmsgq_get(i
->userdata
, &object
, &code
, &data
, &offset
, &chunk
, 0) == 0) {
724 if (!object
&& code
== PA_MESSAGE_SHUTDOWN
) {
725 pa_asyncmsgq_done(i
->userdata
, 0);
726 pa_rtpoll_quit(i
->rtpoll
);
730 ret
= pa_asyncmsgq_dispatch(object
, code
, data
, offset
, &chunk
);
731 pa_asyncmsgq_done(i
->userdata
, ret
);
738 pa_rtpoll_item
*pa_rtpoll_item_new_asyncmsgq_read(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_asyncmsgq
*q
) {
740 struct pollfd
*pollfd
;
745 i
= pa_rtpoll_item_new(p
, prio
, 1);
747 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
748 pollfd
->fd
= pa_asyncmsgq_read_fd(q
);
749 pollfd
->events
= POLLIN
;
751 i
->before_cb
= asyncmsgq_read_before
;
752 i
->after_cb
= asyncmsgq_read_after
;
753 i
->work_cb
= asyncmsgq_read_work
;
759 static int asyncmsgq_write_before(pa_rtpoll_item
*i
) {
762 pa_asyncmsgq_write_before_poll(i
->userdata
);
766 static void asyncmsgq_write_after(pa_rtpoll_item
*i
) {
769 pa_assert((i
->pollfd
[0].revents
& ~POLLIN
) == 0);
770 pa_asyncmsgq_write_after_poll(i
->userdata
);
773 pa_rtpoll_item
*pa_rtpoll_item_new_asyncmsgq_write(pa_rtpoll
*p
, pa_rtpoll_priority_t prio
, pa_asyncmsgq
*q
) {
775 struct pollfd
*pollfd
;
780 i
= pa_rtpoll_item_new(p
, prio
, 1);
782 pollfd
= pa_rtpoll_item_get_pollfd(i
, NULL
);
783 pollfd
->fd
= pa_asyncmsgq_write_fd(q
);
784 pollfd
->events
= POLLIN
;
786 i
->before_cb
= asyncmsgq_write_before
;
787 i
->after_cb
= asyncmsgq_write_after
;
794 void pa_rtpoll_quit(pa_rtpoll
*p
) {