From 6b8fdc41693a710a29c4d3851a8c870031f1af88 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 01:19:55 +0200 Subject: CANCELLED vs. CANCELED Define CANCELLED as alias for CANCELED --- src/pulse/def.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/def.h b/src/pulse/def.h index 1a7da974..e839bd92 100644 --- a/src/pulse/def.h +++ b/src/pulse/def.h @@ -95,13 +95,14 @@ static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x) { typedef enum pa_operation_state { PA_OPERATION_RUNNING, /**< The operation is still running */ PA_OPERATION_DONE, /**< The operation has been completed */ - PA_OPERATION_CANCELED /**< The operation has been canceled */ + PA_OPERATION_CANCELLED /**< The operation has been cancelled. Before 0.9.18 this was called PA_OPERATION_CANCELED. That name is still available for compatibility. */ } pa_operation_state_t; /** \cond fulldocs */ #define PA_OPERATION_RUNNING PA_OPERATION_RUNNING #define PA_OPERATION_DONE PA_OPERATION_DONE -#define PA_OPERATION_CANCELED PA_OPERATION_CANCELED +#define PA_OPERATION_CANCELED PA_OPERATION_CANCELLED +#define PA_OPERATION_CANCELLED PA_OPERATION_CANCELLED /** \endcond */ /** An invalid index */ -- cgit From cdbeac6b6961b5e071250f539b7011efe65ef513 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 01:37:23 +0200 Subject: libpulse: as a special exception, don't require a non-NULL context in pa_context_errno --- src/pulse/context.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/context.c b/src/pulse/context.c index 894ab2e0..23ae30ce 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -1045,7 +1045,10 @@ pa_context_state_t pa_context_get_state(pa_context *c) { } int pa_context_errno(pa_context *c) { - pa_assert(c); + + if (!c) + return PA_ERR_INVALID; + pa_assert(PA_REFCNT_VALUE(c) >= 1); return c->error; -- cgit From 94f28b9d4b7448c1e9bb6fb8a3b44f53988f6aa5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Sep 2009 02:22:41 +0200 Subject: proplist: introduce PA_PROP_WINDOW_DESKTOP property --- src/pulse/proplist.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/pulse') diff --git a/src/pulse/proplist.h b/src/pulse/proplist.h index 8bf9c482..8dff8df4 100644 --- a/src/pulse/proplist.h +++ b/src/pulse/proplist.h @@ -115,6 +115,9 @@ PA_C_DECL_BEGIN /** For streams that belong to a window on the screen: relative position of the window center on the screen, float formatted as text string, ranging from 0.0 (top of the screen) to 1.0 (bottom of the screen). e.g. "0.43". \since 0.9.17 */ #define PA_PROP_WINDOW_VPOS "window.vpos" +/** For streams that belong to a window on the screen: if the windowing system supports multiple desktops, a comma seperated list of indexes of the desktops this window is visible on. If this property is an empty string, it is visible on all desktops (i.e. 'sticky'). The first desktop is 0. e.g. "0,2,3" \since 0.9.18 */ +#define PA_PROP_WINDOW_DESKTOP "window.desktop" + /** For streams that belong to an X11 window on the screen: the X11 display string. e.g. ":0.0" */ #define PA_PROP_WINDOW_X11_DISPLAY "window.x11.display" -- cgit 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') 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') 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') 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') 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') 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 f7d38965b355b4932e7a17774e4625f57248f845 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:07:12 +0200 Subject: timeval: introduce PA_USEC_MAX --- src/pulse/timeval.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.h b/src/pulse/timeval.h index 48c6cdb3..3cea5d3b 100644 --- a/src/pulse/timeval.h +++ b/src/pulse/timeval.h @@ -51,12 +51,15 @@ PA_C_DECL_BEGIN /** The number of nanoseconds in a microsecond */ #define PA_NSEC_PER_USEC ((unsigned long long) 1000ULL) -/** Invalid time in usec */ +/** Invalid time in usec. \since 0.9.15 */ #define PA_USEC_INVALID ((pa_usec_t) -1) +/** Biggest time in usec. \since 0.9.18 */ +#define PA_USEC_MAX ((pa_usec_t) -2) + struct timeval; -/** Return the current timestamp, just like UNIX gettimeofday() */ +/** Return the current wallclock timestamp, just like UNIX gettimeofday(). */ struct timeval *pa_gettimeofday(struct timeval *tv); /** Calculate the difference between the two specified timeval -- cgit From 05f6236a83414573587c73dbc439e68dae5f529e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:10:26 +0200 Subject: timeval: make pa_timeval_sub saturating --- src/pulse/timeval.c | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 376cf13c..1a0d3cef 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -33,6 +33,7 @@ #include #include +#include #include "timeval.h" @@ -54,9 +55,9 @@ struct timeval *pa_gettimeofday(struct timeval *tv) { #define EPOCHFILETIME (116444736000000000LL) #endif - FILETIME ft; - LARGE_INTEGER li; - __int64 t; + FILETIME ft; + LARGE_INTEGER li; + int64_t t; pa_assert(tv); @@ -128,40 +129,65 @@ pa_usec_t pa_timeval_age(const struct timeval *tv) { } struct timeval* pa_timeval_add(struct timeval *tv, pa_usec_t v) { - unsigned long secs; + time_t secs; pa_assert(tv); - secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec += (time_t) secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; + secs = (time_t) (v/PA_USEC_PER_SEC); + if (PA_UNLIKELY(tv->tv_sec > PA_INT_TYPE_MAX(time_t) - secs)) + goto overflow; + + tv->tv_sec += secs; + v -= (pa_usec_t) secs * PA_USEC_PER_SEC; tv->tv_usec += (suseconds_t) v; /* Normalize */ - while ((unsigned) tv->tv_usec >= PA_USEC_PER_SEC) { + while ((pa_usec_t) tv->tv_usec >= PA_USEC_PER_SEC) { + + if (PA_UNLIKELY(tv->tv_sec >= PA_INT_TYPE_MAX(time_t))) + goto overflow; + tv->tv_sec++; tv->tv_usec -= (suseconds_t) PA_USEC_PER_SEC; } return tv; + +overflow: + tv->tv_sec = PA_INT_TYPE_MAX(time_t); + tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1); + return tv; } struct timeval* pa_timeval_sub(struct timeval *tv, pa_usec_t v) { - unsigned long secs; + time_t secs; pa_assert(tv); - secs = (unsigned long) (v/PA_USEC_PER_SEC); - tv->tv_sec -= (time_t) secs; - v -= ((pa_usec_t) secs) * PA_USEC_PER_SEC; + secs = (time_t) (v/PA_USEC_PER_SEC); + + if (PA_UNLIKELY(tv->tv_sec < secs)) + goto underflow; + + tv->tv_sec -= secs; + v -= (pa_usec_t) secs * PA_USEC_PER_SEC; if (tv->tv_usec >= (suseconds_t) v) tv->tv_usec -= (suseconds_t) v; else { + + if (PA_UNLIKELY(tv->tv_sec <= 0)) + goto underflow; + tv->tv_sec --; tv->tv_usec += (suseconds_t) (PA_USEC_PER_SEC - v); } return tv; + +underflow: + tv->tv_sec = 0; + tv->tv_usec = 0; + return tv; } struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { -- cgit From a1da83b206d4a73bfa537ab3694bac7244bd19a1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:11:02 +0200 Subject: timeval: add UNLIKELY annotation --- src/pulse/timeval.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 1a0d3cef..87569cf1 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -83,7 +83,7 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { pa_assert(b); /* Check which whan is the earlier time and swap the two arguments if required. */ - if (pa_timeval_cmp(a, b) < 0) { + if (PA_UNLIKELY(pa_timeval_cmp(a, b) < 0)) { const struct timeval *c; c = a; a = b; @@ -95,9 +95,9 @@ pa_usec_t pa_timeval_diff(const struct timeval *a, const struct timeval *b) { /* Calculate the microsecond difference */ if (a->tv_usec > b->tv_usec) - r += ((pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec); + r += (pa_usec_t) a->tv_usec - (pa_usec_t) b->tv_usec; else if (a->tv_usec < b->tv_usec) - r -= ((pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec); + r -= (pa_usec_t) b->tv_usec - (pa_usec_t) a->tv_usec; return r; } -- cgit From c024aeaae91c139914dc928df975ea311729052c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2009 04:11:59 +0200 Subject: timeval: make timeval conversion routines handle PA_USEC_INVALID special --- src/pulse/timeval.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/pulse') diff --git a/src/pulse/timeval.c b/src/pulse/timeval.c index 87569cf1..cde4417c 100644 --- a/src/pulse/timeval.c +++ b/src/pulse/timeval.c @@ -193,6 +193,13 @@ underflow: struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { pa_assert(tv); + if (PA_UNLIKELY(v == PA_USEC_INVALID)) { + tv->tv_sec = PA_INT_TYPE_MAX(time_t); + tv->tv_usec = (suseconds_t) (PA_USEC_PER_SEC-1); + + return tv; + } + tv->tv_sec = (time_t) (v / PA_USEC_PER_SEC); tv->tv_usec = (suseconds_t) (v % PA_USEC_PER_SEC); @@ -200,7 +207,9 @@ struct timeval* pa_timeval_store(struct timeval *tv, pa_usec_t v) { } pa_usec_t pa_timeval_load(const struct timeval *tv) { - pa_assert(tv); + + if (PA_UNLIKELY(!tv)) + return PA_USEC_INVALID; return (pa_usec_t) tv->tv_sec * PA_USEC_PER_SEC + -- 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') 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') 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