mainloop: convert from wallclock to rtclock

This is needed for the mainloop timeouts
This commit is contained in:
Wim Taymans 2020-10-22 16:46:29 +02:00
parent 70e9e622eb
commit 413c233b9a
3 changed files with 58 additions and 24 deletions

View file

@ -508,6 +508,9 @@ struct pa_operation
bool pa_mainloop_api_is_pipewire(pa_mainloop_api *api);
#define PA_TIMEVAL_RTCLOCK ((time_t) (1LU << 30))
struct timeval* pa_rtclock_from_wallclock(struct timeval *tv);
pa_operation *pa_operation_new(pa_context *c, pa_stream *s, pa_operation_cb_t cb, size_t userdata_size);
void pa_operation_done(pa_operation *o);
int pa_operation_sync(pa_operation *o);

View file

@ -116,48 +116,46 @@ static void source_timer_func(void *data, uint64_t expirations)
ev->cb(&ev->mainloop->api, ev, &tv, ev->userdata);
}
static void set_timer(pa_time_event *ev, const struct timeval *tv)
{
pa_mainloop *mainloop = ev->mainloop;
struct timespec ts;
struct timeval ttv = *tv;
if (tv == NULL) {
ts.tv_sec = 0;
ts.tv_nsec = 1;
} else {
if ((tv->tv_usec & PA_TIMEVAL_RTCLOCK) == 0)
pa_rtclock_from_wallclock(&ttv);
ts.tv_sec = ttv.tv_sec;
ts.tv_nsec = ttv.tv_usec * 1000LL;
}
pw_log_debug("set timer %p %ld %ld", ev, ts.tv_sec, ts.tv_nsec);
pw_loop_update_timer(mainloop->loop, ev->source, &ts, NULL, true);
}
static pa_time_event* api_time_new(pa_mainloop_api*a, const struct timeval *tv, pa_time_event_cb_t cb, void *userdata)
{
pa_mainloop *mainloop = SPA_CONTAINER_OF(a, pa_mainloop, api);
pa_time_event *ev;
struct timespec ts;
ev = calloc(1, sizeof(pa_time_event));
ev->source = pw_loop_add_timer(mainloop->loop, source_timer_func, ev);
ev->mainloop = mainloop;
ev->cb = cb;
ev->userdata = userdata;
pw_log_debug("new timer %p", ev);
if (tv == NULL) {
ts.tv_sec = 0;
ts.tv_nsec = 1;
}
else {
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000LL;
}
pw_log_debug("new timer %p %ld %ld", ev, ts.tv_sec, ts.tv_nsec);
pw_loop_update_timer(mainloop->loop, ev->source, &ts, NULL, true);
set_timer(ev, tv);
return ev;
}
static void api_time_restart(pa_time_event* e, const struct timeval *tv)
{
struct timespec ts;
pa_assert(e);
if (tv == NULL) {
ts.tv_sec = 0;
ts.tv_nsec = 1;
}
else {
ts.tv_sec = tv->tv_sec;
ts.tv_nsec = tv->tv_usec * 1000LL;
}
pw_log_debug("io %p", e);
pw_loop_update_timer(e->mainloop->loop, e->source, &ts, NULL, true);
set_timer(e, tv);
}
static void api_time_free(pa_time_event* e)

View file

@ -23,7 +23,9 @@
#include <pipewire/log.h>
#include <pulse/timeval.h>
#include <pulse/rtclock.h>
#include "internal.h"
SPA_EXPORT
pa_usec_t pa_rtclock_now(void)
@ -36,3 +38,34 @@ pa_usec_t pa_rtclock_now(void)
return res;
}
static struct timeval *pa_rtclock_get(struct timeval *tv)
{
struct timespec ts;
pa_assert(tv);
clock_gettime(CLOCK_MONOTONIC, &ts);
tv->tv_sec = ts.tv_sec;
tv->tv_usec = ts.tv_nsec / PA_NSEC_PER_USEC;
return tv;
}
struct timeval* pa_rtclock_from_wallclock(struct timeval *tv)
{
struct timeval wc_now, rt_now;
pa_assert(tv);
pa_gettimeofday(&wc_now);
pa_rtclock_get(&rt_now);
if (pa_timeval_cmp(&wc_now, tv) < 0)
pa_timeval_add(&rt_now, pa_timeval_diff(tv, &wc_now));
else
pa_timeval_sub(&rt_now, pa_timeval_diff(&wc_now, tv));
*tv = rt_now;
return tv;
}