From a43118b730c60a17b032b882b10ff9b93ab59460 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 03:48:55 +0200 Subject: mainloop: properly convert time to wallclock time when handing it to the user --- src/pulse/mainloop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 93a4742d..379f88a8 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -806,7 +806,7 @@ static int dispatch_timeout(pa_mainloop *m) { /* Disable time event */ mainloop_time_restart(e, NULL); - e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, TRUE), e->userdata); + e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, FALSE), e->userdata); r++; } -- cgit From a049909a7044813cb6237d22757ac24081b59af8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 03:59:40 +0200 Subject: mainloop: calculate in pa_usec_t everywhere --- src/pulse/mainloop.c | 67 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 21 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 379f88a8..d2cc7aec 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -112,7 +112,7 @@ struct pa_mainloop { struct pollfd *pollfds; unsigned max_pollfds, n_pollfds; - int prepared_timeout; + pa_usec_t prepared_timeout; pa_time_event *cached_next_time_event; pa_mainloop_api api; @@ -320,21 +320,19 @@ static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy } /* Time events */ -static pa_usec_t timeval_load(const struct timeval *tv) { - pa_bool_t is_rtclock; +static pa_usec_t make_rt(const struct timeval *tv) { struct timeval ttv; if (!tv) return PA_USEC_INVALID; - ttv = *tv; - is_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK); - ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; - - if (!is_rtclock) - pa_rtclock_from_wallclock(&ttv); + if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { + ttv = *tv; + ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; + tv = pa_rtclock_from_wallclock(&ttv); + } - return pa_timeval_load(&ttv); + return pa_timeval_load(tv); } static pa_time_event* mainloop_time_new( @@ -351,7 +349,7 @@ static pa_time_event* mainloop_time_new( pa_assert(a->userdata); pa_assert(callback); - t = timeval_load(tv); + t = make_rt(tv); m = a->userdata; pa_assert(a == &m->api); @@ -392,7 +390,7 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { pa_assert(e); pa_assert(!e->dead); - t = timeval_load(tv); + t = make_rt(tv); valid = (t != PA_USEC_INVALID); if (e->enabled && !valid) { @@ -763,12 +761,12 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) { return n; } -static int calc_next_timeout(pa_mainloop *m) { +static pa_usec_t calc_next_timeout(pa_mainloop *m) { pa_time_event *t; pa_usec_t clock_now; - if (!m->n_enabled_time_events) - return -1; + if (m->n_enabled_time_events <= 0) + return PA_USEC_INVALID; pa_assert_se(t = find_next_time_event(m)); @@ -780,7 +778,7 @@ static int calc_next_timeout(pa_mainloop *m) { if (t->time <= clock_now) return 0; - return (int) ((t->time - clock_now) / 1000); /* in milliseconds */ + return t->time - clock_now; } static int dispatch_timeout(pa_mainloop *m) { @@ -850,12 +848,17 @@ int pa_mainloop_prepare(pa_mainloop *m, int timeout) { goto quit; if (m->n_enabled_defer_events <= 0) { + if (m->rebuild_pollfds) rebuild_pollfds(m); m->prepared_timeout = calc_next_timeout(m); - if (timeout >= 0 && (timeout < m->prepared_timeout || m->prepared_timeout < 0)) - m->prepared_timeout = timeout; + if (timeout >= 0) { + uint64_t u = (uint64_t) timeout * PA_USEC_PER_MSEC; + + if (u < m->prepared_timeout || m->prepared_timeout == PA_USEC_INVALID) + m->prepared_timeout = timeout; + } } m->state = STATE_PREPARED; @@ -866,6 +869,13 @@ quit: return -2; } +static int usec_to_timeout(pa_usec_t u) { + if (u == PA_USEC_INVALID) + return -1; + + return (u + PA_USEC_PER_MSEC - 1) / PA_USEC_PER_MSEC; +} + int pa_mainloop_poll(pa_mainloop *m) { pa_assert(m); pa_assert(m->state == STATE_PREPARED); @@ -881,9 +891,24 @@ int pa_mainloop_poll(pa_mainloop *m) { pa_assert(!m->rebuild_pollfds); if (m->poll_func) - m->poll_func_ret = m->poll_func(m->pollfds, m->n_pollfds, m->prepared_timeout, m->poll_func_userdata); - else - m->poll_func_ret = poll(m->pollfds, m->n_pollfds, m->prepared_timeout); + m->poll_func_ret = m->poll_func( + m->pollfds, m->n_pollfds, + usec_to_timeout(m->prepared_timeout), + m->poll_func_userdata); + else { +#ifdef HAVE_PPOLL + struct timespec ts; + + m->poll_func_ret = ppoll( + m->pollfds, m->n_pollfds, + m->prepared_timeout == PA_USEC_INVALID ? NULL : pa_timespec_store(&ts, m->prepared_timeout), + NULL); +#else + m->poll_func_ret = poll( + m->pollfds, m->n_pollfds, + usec_to_timeout(m->prepared_timeout)); +#endif + } if (m->poll_func_ret < 0) { if (errno == EINTR) -- cgit From b32f5994e9d1872c3a2ed8fd44d6d1866bb8387f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:00:38 +0200 Subject: mainloop: don't initialize fields we don't have to --- src/pulse/mainloop.c | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index d2cc7aec..4f3b676f 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -172,17 +172,14 @@ static pa_io_event* mainloop_io_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_io_event, 1); + e = pa_xnew0(pa_io_event, 1); e->mainloop = m; - e->dead = FALSE; e->fd = fd; e->events = events; - e->pollfd = NULL; e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; #ifdef OS_IS_WIN32 { @@ -265,16 +262,14 @@ static pa_defer_event* mainloop_defer_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_defer_event, 1); + e = pa_xnew0(pa_defer_event, 1); e->mainloop = m; - e->dead = FALSE; e->enabled = TRUE; m->n_enabled_defer_events++; e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; PA_LLIST_PREPEND(pa_defer_event, m->defer_events, e); @@ -354,9 +349,8 @@ static pa_time_event* mainloop_time_new( m = a->userdata; pa_assert(a == &m->api); - e = pa_xnew(pa_time_event, 1); + e = pa_xnew0(pa_time_event, 1); e->mainloop = m; - e->dead = FALSE; if ((e->enabled = (t != PA_USEC_INVALID))) { e->time = t; @@ -373,7 +367,6 @@ static pa_time_event* mainloop_time_new( e->callback = callback; e->userdata = userdata; - e->destroy_callback = NULL; PA_LLIST_PREPEND(pa_time_event, m->time_events, e); @@ -478,9 +471,8 @@ pa_mainloop *pa_mainloop_new(void) { pa_init_i18n(); - m = pa_xnew(pa_mainloop, 1); + m = pa_xnew0(pa_mainloop, 1); - m->wakeup_pipe_type = 0; if (pipe(m->wakeup_pipe) < 0) { pa_log_error("ERROR: cannot create wakeup pipe"); pa_xfree(m); @@ -491,32 +483,14 @@ pa_mainloop *pa_mainloop_new(void) { pa_make_fd_nonblock(m->wakeup_pipe[1]); pa_make_fd_cloexec(m->wakeup_pipe[0]); pa_make_fd_cloexec(m->wakeup_pipe[1]); - m->wakeup_requested = FALSE; - PA_LLIST_HEAD_INIT(pa_io_event, m->io_events); - PA_LLIST_HEAD_INIT(pa_time_event, m->time_events); - PA_LLIST_HEAD_INIT(pa_defer_event, m->defer_events); - - m->n_enabled_defer_events = m->n_enabled_time_events = m->n_io_events = 0; - m->io_events_please_scan = m->time_events_please_scan = m->defer_events_please_scan = 0; - - m->cached_next_time_event = NULL; - m->prepared_timeout = 0; - - m->pollfds = NULL; - m->max_pollfds = m->n_pollfds = 0; m->rebuild_pollfds = TRUE; - m->quit = FALSE; - m->retval = 0; - m->api = vtable; m->api.userdata = m; m->state = STATE_PASSIVE; - m->poll_func = NULL; - m->poll_func_userdata = NULL; m->poll_func_ret = -1; return m; -- cgit From 18d69c5d9d04d81135f078d7f49bad3214418622 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:03:49 +0200 Subject: mainloop: use PA_LLIST_FOREACH macros where applicable --- src/pulse/mainloop.c | 56 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 26 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 4f3b676f..67f095be 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -497,11 +497,9 @@ pa_mainloop *pa_mainloop_new(void) { } static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) { - pa_io_event *e; + pa_io_event *e, *n; - e = m->io_events; - while (e) { - pa_io_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->io_events) { if (!force && m->io_events_please_scan <= 0) break; @@ -521,19 +519,15 @@ static void cleanup_io_events(pa_mainloop *m, pa_bool_t force) { m->rebuild_pollfds = TRUE; } - - e = n; } pa_assert(m->io_events_please_scan == 0); } static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) { - pa_time_event *e; + pa_time_event *e, *n; - e = m->time_events; - while (e) { - pa_time_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->time_events) { if (!force && m->time_events_please_scan <= 0) break; @@ -557,19 +551,15 @@ static void cleanup_time_events(pa_mainloop *m, pa_bool_t force) { pa_xfree(e); } - - e = n; } pa_assert(m->time_events_please_scan == 0); } static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) { - pa_defer_event *e; + pa_defer_event *e, *n; - e = m->defer_events; - while (e) { - pa_defer_event *n = e->next; + PA_LLIST_FOREACH_SAFE(e, n, m->defer_events) { if (!force && m->defer_events_please_scan <= 0) break; @@ -593,8 +583,6 @@ static void cleanup_defer_events(pa_mainloop *m, pa_bool_t force) { pa_xfree(e); } - - e = n; } pa_assert(m->defer_events_please_scan == 0); @@ -651,7 +639,7 @@ static void rebuild_pollfds(pa_mainloop *m) { m->n_pollfds++; } - for (e = m->io_events; e; e = e->next) { + PA_LLIST_FOREACH(e, m->io_events) { if (e->dead) { e->pollfd = NULL; continue; @@ -675,16 +663,22 @@ static int dispatch_pollfds(pa_mainloop *m) { pa_assert(m->poll_func_ret > 0); - for (e = m->io_events, k = m->poll_func_ret; e && !m->quit && k > 0; e = e->next) { + k = m->poll_func_ret; + + PA_LLIST_FOREACH(e, m->io_events) { + + if (k <= 0 || m->quit) + break; + if (e->dead || !e->pollfd || !e->pollfd->revents) continue; pa_assert(e->pollfd->fd == e->fd); pa_assert(e->callback); + e->callback(&m->api, e, e->fd, map_flags_from_libc(e->pollfd->revents), e->userdata); e->pollfd->revents = 0; r++; - k--; } @@ -698,7 +692,11 @@ static int dispatch_defer(pa_mainloop *m) { if (m->n_enabled_defer_events <= 0) return 0; - for (e = m->defer_events; e && !m->quit; e = e->next) { + PA_LLIST_FOREACH(e, m->defer_events) { + + if (m->quit) + break; + if (e->dead || !e->enabled) continue; @@ -717,7 +715,7 @@ static pa_time_event* find_next_time_event(pa_mainloop *m) { if (m->cached_next_time_event) return m->cached_next_time_event; - for (t = m->time_events; t; t = t->next) { + PA_LLIST_FOREACH(t, m->time_events) { if (t->dead || !t->enabled) continue; @@ -766,7 +764,10 @@ static int dispatch_timeout(pa_mainloop *m) { now = pa_rtclock_now(); - for (e = m->time_events; e && !m->quit; e = e->next) { + PA_LLIST_FOREACH(e, m->time_events) { + + if (m->quit) + break; if (e->dead || !e->enabled) continue; @@ -806,7 +807,8 @@ static void clear_wakeup(pa_mainloop *m) { return; if (m->wakeup_requested) { - while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)); + while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)) + ; m->wakeup_requested = 0; } } @@ -964,7 +966,8 @@ quit: int pa_mainloop_run(pa_mainloop *m, int *retval) { int r; - while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0); + while ((r = pa_mainloop_iterate(m, 1, retval)) >= 0) + ; if (r == -2) return 1; @@ -984,6 +987,7 @@ void pa_mainloop_quit(pa_mainloop *m, int retval) { pa_mainloop_api* pa_mainloop_get_api(pa_mainloop*m) { pa_assert(m); + return &m->api; } -- cgit From fb4a2a1bbbd35601b5da62037c1cee40be859428 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:05:10 +0200 Subject: mainloop: sum up dispatched events in an unsigned to clarify range --- src/pulse/mainloop.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 67f095be..62659d89 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -657,9 +657,9 @@ static void rebuild_pollfds(pa_mainloop *m) { m->rebuild_pollfds = FALSE; } -static int dispatch_pollfds(pa_mainloop *m) { +static unsigned dispatch_pollfds(pa_mainloop *m) { pa_io_event *e; - int r = 0, k; + unsigned r = 0, k; pa_assert(m->poll_func_ret > 0); @@ -685,9 +685,9 @@ static int dispatch_pollfds(pa_mainloop *m) { return r; } -static int dispatch_defer(pa_mainloop *m) { +static unsigned dispatch_defer(pa_mainloop *m) { pa_defer_event *e; - int r = 0; + unsigned r = 0; if (m->n_enabled_defer_events <= 0) return 0; @@ -753,10 +753,10 @@ static pa_usec_t calc_next_timeout(pa_mainloop *m) { return t->time - clock_now; } -static int dispatch_timeout(pa_mainloop *m) { +static unsigned dispatch_timeout(pa_mainloop *m) { pa_time_event *e; pa_usec_t now; - int r = 0; + unsigned r = 0; pa_assert(m); if (m->n_enabled_time_events <= 0) @@ -903,7 +903,7 @@ quit: } int pa_mainloop_dispatch(pa_mainloop *m) { - int dispatched = 0; + unsigned dispatched = 0; pa_assert(m); pa_assert(m->state == STATE_POLLED); @@ -929,7 +929,7 @@ int pa_mainloop_dispatch(pa_mainloop *m) { m->state = STATE_PASSIVE; - return dispatched; + return (int) dispatched; quit: m->state = STATE_QUIT; @@ -938,6 +938,7 @@ quit: int pa_mainloop_get_retval(pa_mainloop *m) { pa_assert(m); + return m->retval; } -- cgit From d6291511a25d29c51cc3b22b72b69426f68e461d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:21:01 +0200 Subject: mainloop: pass monotonic times back to user if he passed monotonic times to us --- src/pulse/mainloop.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 62659d89..c5443f23 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -78,6 +78,7 @@ struct pa_time_event { pa_bool_t dead:1; pa_bool_t enabled:1; + pa_bool_t use_rtclock:1; pa_usec_t time; pa_time_event_cb_t callback; @@ -315,17 +316,22 @@ static void mainloop_defer_set_destroy(pa_defer_event *e, pa_defer_event_destroy } /* Time events */ -static pa_usec_t make_rt(const struct timeval *tv) { +static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) { struct timeval ttv; - if (!tv) + if (!tv) { + *use_rtclock = FALSE; return PA_USEC_INVALID; + } if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { ttv = *tv; ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; tv = pa_rtclock_from_wallclock(&ttv); - } + + *use_rtclock = TRUE; + } else + *use_rtclock = FALSE; return pa_timeval_load(tv); } @@ -339,12 +345,13 @@ static pa_time_event* mainloop_time_new( pa_mainloop *m; pa_time_event *e; pa_usec_t t; + pa_bool_t use_rtclock = FALSE; pa_assert(a); pa_assert(a->userdata); pa_assert(callback); - t = make_rt(tv); + t = make_rt(tv, &use_rtclock); m = a->userdata; pa_assert(a == &m->api); @@ -354,6 +361,7 @@ static pa_time_event* mainloop_time_new( if ((e->enabled = (t != PA_USEC_INVALID))) { e->time = t; + e->use_rtclock= use_rtclock; m->n_enabled_time_events++; @@ -379,11 +387,12 @@ static pa_time_event* mainloop_time_new( static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { pa_bool_t valid; pa_usec_t t; + pa_bool_t use_rtclock = FALSE; pa_assert(e); pa_assert(!e->dead); - t = make_rt(tv); + t = make_rt(tv, &use_rtclock); valid = (t != PA_USEC_INVALID); if (e->enabled && !valid) { @@ -394,6 +403,7 @@ static void mainloop_time_restart(pa_time_event *e, const struct timeval *tv) { if ((e->enabled = valid)) { e->time = t; + e->use_rtclock = use_rtclock; pa_mainloop_wakeup(e->mainloop); } @@ -779,7 +789,7 @@ static unsigned dispatch_timeout(pa_mainloop *m) { /* Disable time event */ mainloop_time_restart(e, NULL); - e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, FALSE), e->userdata); + e->callback(&m->api, e, pa_timeval_rtstore(&tv, e->time, e->use_rtclock), e->userdata); r++; } -- cgit From f84d755d6a90ce8752e063a8a04a5d91239eb348 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 22:14:55 +0200 Subject: mainloop: fix detection of rt clocks --- src/pulse/mainloop.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'src/pulse/mainloop.c') diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index c5443f23..090ac8c2 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -324,16 +324,15 @@ static pa_usec_t make_rt(const struct timeval *tv, pa_bool_t *use_rtclock) { return PA_USEC_INVALID; } - if (tv->tv_usec & PA_TIMEVAL_RTCLOCK) { - ttv = *tv; - ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; - tv = pa_rtclock_from_wallclock(&ttv); + ttv = *tv; + *use_rtclock = !!(ttv.tv_usec & PA_TIMEVAL_RTCLOCK); - *use_rtclock = TRUE; - } else - *use_rtclock = FALSE; + if (*use_rtclock) + ttv.tv_usec &= ~PA_TIMEVAL_RTCLOCK; + else + pa_rtclock_from_wallclock(&ttv); - return pa_timeval_load(tv); + return pa_timeval_load(&ttv); } static pa_time_event* mainloop_time_new( -- cgit