Base mainloop on pa_rtclock_now()

Move the mainloop to monotonic based time events.

Introduces 4 helper functions:
pa_{context,core}_rttime_{new,restart}(), that fill correctly a
timeval with the rtclock flag set if the mainloop supports it.

Both mainloop-test and mainloop-test-glib works with rt and timeval
based time events. PulseAudio and clients should be fully functional.

This patch has received several iterations, and this one as been
largely untested.

Signed-off-by: Marc-André Lureau <marca-andre.lureau@nokia.com>
This commit is contained in:
Marc-André Lureau 2009-04-05 02:13:43 +03:00 committed by Marc-André Lureau
parent 125c528896
commit 0955e3d45b
42 changed files with 311 additions and 233 deletions

View file

@ -35,6 +35,7 @@
#include <pulse/volume.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
#include <pulse/rtclock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/module.h>
@ -53,7 +54,7 @@ PA_MODULE_DESCRIPTION("Automatically restore profile of cards");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(TRUE);
#define SAVE_INTERVAL 10
#define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
static const char* const valid_modargs[] = {
NULL
@ -75,12 +76,11 @@ struct entry {
char profile[PA_NAME_MAX];
} PA_GCC_PACKED ;
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
pa_assert(a);
pa_assert(e);
pa_assert(tv);
pa_assert(u);
pa_assert(e == u->save_time_event);
@ -132,14 +132,10 @@ fail:
}
static void trigger_save(struct userdata *u) {
struct timeval tv;
if (u->save_time_event)
return;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
}
static void subscribe_callback(pa_core *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) {

View file

@ -225,9 +225,8 @@ static void adjust_rates(struct userdata *u) {
pa_asyncmsgq_send(u->sink->asyncmsgq, PA_MSGOBJECT(u->sink), SINK_MESSAGE_UPDATE_LATENCY, NULL, (int64_t) avg_total_latency, NULL);
}
static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
static void time_callback(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
struct timeval n;
pa_assert(u);
pa_assert(a);
@ -235,9 +234,7 @@ static void time_callback(pa_mainloop_api*a, pa_time_event* e, const struct time
adjust_rates(u);
pa_gettimeofday(&n);
n.tv_sec += (time_t) u->adjust_time;
u->sink->core->mainloop->time_restart(e, &n);
pa_core_rttime_restart(u->core, e, pa_rtclock_now() + u->adjust_time * PA_USEC_PER_SEC);
}
static void process_render_null(struct userdata *u, pa_usec_t now) {
@ -1171,12 +1168,8 @@ int pa__init(pa_module*m) {
if (o->sink_input)
pa_sink_input_put(o->sink_input);
if (u->adjust_time > 0) {
struct timeval tv;
pa_gettimeofday(&tv);
tv.tv_sec += (time_t) u->adjust_time;
u->time_event = m->core->mainloop->time_new(m->core->mainloop, &tv, time_callback, u);
}
if (u->adjust_time > 0)
u->time_event = pa_core_rttime_new(m->core, pa_rtclock_now() + u->adjust_time * PA_USEC_PER_SEC, time_callback, u);
pa_modargs_free(ma);

View file

@ -26,6 +26,7 @@
#include <errno.h>
#include <stdio.h>
#include <pulse/rtclock.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
@ -42,7 +43,7 @@ PA_MODULE_DESCRIPTION("Automatically restore the default sink and source");
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(TRUE);
#define DEFAULT_SAVE_INTERVAL 5
#define SAVE_INTERVAL (5 * PA_USEC_PER_SEC)
struct userdata {
pa_core *core;
@ -127,7 +128,7 @@ static void save(struct userdata *u) {
u->modified = FALSE;
}
static void time_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *tv, void *userdata) {
static void time_cb(pa_mainloop_api *a, pa_time_event *e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
pa_assert(u);
@ -146,12 +147,8 @@ static void subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t id
u->modified = TRUE;
if (!u->time_event) {
struct timeval tv;
pa_gettimeofday(&tv);
pa_timeval_add(&tv, DEFAULT_SAVE_INTERVAL*PA_USEC_PER_SEC);
u->time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, time_cb, u);
}
if (!u->time_event)
u->time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, time_cb, u);
}
int pa__init(pa_module *m) {

View file

@ -35,6 +35,7 @@
#include <pulse/volume.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
#include <pulse/rtclock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/module.h>
@ -58,7 +59,7 @@ PA_MODULE_USAGE(
"restore_volume=<Save/restore volumes?> "
"restore_muted=<Save/restore muted states?>");
#define SAVE_INTERVAL 10
#define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
static const char* const valid_modargs[] = {
"restore_volume",
@ -95,12 +96,11 @@ struct entry {
char port[PA_NAME_MAX];
} PA_GCC_PACKED;
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
pa_assert(a);
pa_assert(e);
pa_assert(tv);
pa_assert(u);
pa_assert(e == u->save_time_event);
@ -162,14 +162,10 @@ fail:
}
static void trigger_save(struct userdata *u) {
struct timeval tv;
if (u->save_time_event)
return;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
}
static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {

View file

@ -609,7 +609,7 @@ int pa__init(pa_module*m) {
pa_sink_set_asyncmsgq(u->sink, u->thread_mq.inq);
pa_sink_set_rtpoll(u->sink, u->rtpoll);
if (!(u->client = pa_socket_client_new_string(u->core->mainloop, espeaker, ESD_DEFAULT_PORT))) {
if (!(u->client = pa_socket_client_new_string(u->core->mainloop, TRUE, espeaker, ESD_DEFAULT_PORT))) {
pa_log("Failed to connect to server.");
goto fail;
}

View file

@ -35,6 +35,7 @@
#include <pulse/volume.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
#include <pulse/rtclock.h>
#include <pulsecore/core-error.h>
#include <pulsecore/module.h>
@ -61,7 +62,7 @@ PA_MODULE_USAGE(
"restore_volume=<Save/restore volumes?> "
"restore_muted=<Save/restore muted states?>");
#define SAVE_INTERVAL 10
#define SAVE_INTERVAL (10 * PA_USEC_PER_SEC)
#define IDENTIFICATION_PROPERTY "module-stream-restore.id"
static const char* const valid_modargs[] = {
@ -111,12 +112,11 @@ enum {
SUBCOMMAND_EVENT
};
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
static void save_time_callback(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
pa_assert(a);
pa_assert(e);
pa_assert(tv);
pa_assert(u);
pa_assert(e == u->save_time_event);
@ -210,7 +210,6 @@ fail:
}
static void trigger_save(struct userdata *u) {
struct timeval tv;
pa_native_connection *c;
uint32_t idx;
@ -230,9 +229,7 @@ static void trigger_save(struct userdata *u) {
if (u->save_time_event)
return;
pa_gettimeofday(&tv);
tv.tv_sec += SAVE_INTERVAL;
u->save_time_event = u->core->mainloop->time_new(u->core->mainloop, &tv, save_time_callback, u);
u->save_time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + SAVE_INTERVAL, save_time_callback, u);
}
static pa_bool_t entries_equal(const struct entry *a, const struct entry *b) {

View file

@ -25,6 +25,7 @@
#include <pulse/xmalloc.h>
#include <pulse/timeval.h>
#include <pulse/rtclock.h>
#include <pulsecore/core.h>
#include <pulsecore/core-util.h>
@ -75,11 +76,11 @@ struct device_info {
struct userdata *userdata;
pa_sink *sink;
pa_source *source;
struct timeval last_use;
pa_usec_t last_use;
pa_time_event *time_event;
};
static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *tv, void *userdata) {
static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval *t, void *userdata) {
struct device_info *d = userdata;
pa_assert(d);
@ -98,22 +99,20 @@ static void timeout_cb(pa_mainloop_api*a, pa_time_event* e, const struct timeval
}
static void restart(struct device_info *d) {
struct timeval tv;
pa_usec_t now;
const char *s;
uint32_t timeout;
pa_assert(d);
pa_assert(d->sink || d->source);
pa_gettimeofday(&tv);
d->last_use = tv;
d->last_use = now = pa_rtclock_now();
s = pa_proplist_gets(d->sink ? d->sink->proplist : d->source->proplist, "module-suspend-on-idle.timeout");
if (!s || pa_atou(s, &timeout) < 0)
timeout = d->userdata->timeout;
timeout = d->userdata->timeout;
pa_timeval_add(&tv, timeout * PA_USEC_PER_SEC);
d->userdata->core->mainloop->time_restart(d->time_event, &tv);
pa_core_rttime_restart(d->userdata->core, d->time_event, now + timeout * PA_USEC_PER_SEC);
if (d->sink)
pa_log_debug("Sink %s becomes idle, timeout in %u seconds.", d->sink->name, timeout);
@ -338,7 +337,7 @@ static pa_hook_result_t device_new_hook_cb(pa_core *c, pa_object *o, struct user
d->userdata = u;
d->source = source ? pa_source_ref(source) : NULL;
d->sink = sink ? pa_sink_ref(sink) : NULL;
d->time_event = c->mainloop->time_new(c->mainloop, NULL, timeout_cb, d);
d->time_event = pa_core_rttime_new(c, PA_USEC_INVALID, timeout_cb, d);
pa_hashmap_put(u->device_infos, o, d);
if ((d->sink && pa_sink_check_suspend(d->sink) <= 0) ||

View file

@ -113,7 +113,7 @@ static const char* const valid_modargs[] = {
#define DEFAULT_TIMEOUT 5
#define LATENCY_INTERVAL 10
#define LATENCY_INTERVAL (10*PA_USEC_PER_SEC)
#define MIN_NETWORK_LATENCY_USEC (8*PA_USEC_PER_MSEC)
@ -879,9 +879,8 @@ static void request_latency(struct userdata *u) {
}
/* Called from main context */
static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct timeval *tv, void *userdata) {
static void timeout_callback(pa_mainloop_api *m, pa_time_event *e, const struct timeval *t, void *userdata) {
struct userdata *u = userdata;
struct timeval ntv;
pa_assert(m);
pa_assert(e);
@ -889,9 +888,7 @@ static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, const struct
request_latency(u);
pa_gettimeofday(&ntv);
ntv.tv_sec += LATENCY_INTERVAL;
m->time_restart(e, &ntv);
pa_core_rttime_restart(u->core, e, pa_rtclock_now() + LATENCY_INTERVAL);
}
/* Called from main context */
@ -1358,7 +1355,6 @@ static void start_subscribe(struct userdata *u) {
/* Called from main context */
static void create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {
struct userdata *u = userdata;
struct timeval ntv;
#ifdef TUNNEL_SINK
uint32_t bytes;
#endif
@ -1440,9 +1436,7 @@ static void create_stream_callback(pa_pdispatch *pd, uint32_t command, uint32_t
request_info(u);
pa_assert(!u->time_event);
pa_gettimeofday(&ntv);
ntv.tv_sec += LATENCY_INTERVAL;
u->time_event = u->core->mainloop->time_new(u->core->mainloop, &ntv, timeout_callback, u);
u->time_event = pa_core_rttime_new(u->core, pa_rtclock_now() + LATENCY_INTERVAL, timeout_callback, u);
request_latency(u);
@ -1707,7 +1701,7 @@ static void on_connection(pa_socket_client *sc, pa_iochannel *io, void *userdata
}
u->pstream = pa_pstream_new(u->core->mainloop, io, u->core->mempool);
u->pdispatch = pa_pdispatch_new(u->core->mainloop, command_table, PA_COMMAND_MAX);
u->pdispatch = pa_pdispatch_new(u->core->mainloop, TRUE, command_table, PA_COMMAND_MAX);
pa_pstream_set_die_callback(u->pstream, pstream_die_callback, u);
pa_pstream_set_recieve_packet_callback(u->pstream, pstream_packet_callback, u);
@ -1854,7 +1848,7 @@ int pa__init(pa_module*m) {
goto fail;
}
if (!(u->client = pa_socket_client_new_string(m->core->mainloop, u->server_name, PA_NATIVE_DEFAULT_PORT))) {
if (!(u->client = pa_socket_client_new_string(m->core->mainloop, TRUE, u->server_name, PA_NATIVE_DEFAULT_PORT))) {
pa_log("Failed to connect to server '%s'", u->server_name);
goto fail;
}

View file

@ -256,7 +256,7 @@ static void poll_cb(pa_mainloop_api*a, pa_time_event *e, const struct timeval *t
pa_gettimeofday(&ntv);
pa_timeval_add(&ntv, u->poll_timeout);
a->time_restart(e, &ntv);
a->rtclock_time_restart(e, &ntv);
}
static void defer_cb(pa_mainloop_api*a, pa_defer_event *e, void *userdata) {
@ -549,7 +549,7 @@ int pa__init(pa_core *c, pa_module*m) {
pa_gettimeofday(&tv);
pa_timeval_add(&tv, u->poll_timeout);
u->event = c->mainloop->time_new(c->mainloop, &tv, poll_cb, u);
u->event = c->mainloop->rtclock_time_new(c->mainloop, &tv, poll_cb, u);
assert(u->event);
u->defer = c->mainloop->defer_new(c->mainloop, defer_cb, u);

View file

@ -331,7 +331,7 @@ static void rtsp_cb(pa_rtsp_client *rtsp, pa_rtsp_state state, pa_headerlist* he
uint32_t port = pa_rtsp_serverport(c->rtsp);
pa_log_debug("RAOP: RECORDED");
if (!(c->sc = pa_socket_client_new_string(c->core->mainloop, c->host, port))) {
if (!(c->sc = pa_socket_client_new_string(c->core->mainloop, TRUE, c->host, port))) {
pa_log("failed to connect to server '%s:%d'", c->host, port);
return;
}

View file

@ -113,6 +113,7 @@ struct session {
struct userdata {
pa_module *module;
pa_core *core;
pa_sap_context sap_context;
pa_io_event* sap_event;
@ -622,15 +623,13 @@ static void sap_event_cb(pa_mainloop_api *m, pa_io_event *e, int fd, pa_io_event
}
}
static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *ptv, void *userdata) {
static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *tv, void *userdata) {
struct session *s, *n;
struct userdata *u = userdata;
struct timeval now;
struct timeval tv;
pa_assert(m);
pa_assert(t);
pa_assert(ptv);
pa_assert(u);
pa_rtclock_get(&now);
@ -648,9 +647,7 @@ static void check_death_event_cb(pa_mainloop_api *m, pa_time_event *t, const str
}
/* Restart timer */
pa_gettimeofday(&tv);
pa_timeval_add(&tv, DEATH_TIMEOUT*PA_USEC_PER_SEC);
m->time_restart(t, &tv);
pa_core_rttime_restart(u->module->core, t, pa_rtclock_now() + DEATH_TIMEOUT * PA_USEC_PER_SEC);
}
int pa__init(pa_module*m) {
@ -664,7 +661,6 @@ int pa__init(pa_module*m) {
socklen_t salen;
const char *sap_address;
int fd = -1;
struct timeval tv;
pa_assert(m);
@ -697,6 +693,7 @@ int pa__init(pa_module*m) {
m->userdata = u = pa_xnew(struct userdata, 1);
u->module = m;
u->core = m->core;
u->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL));
u->sap_event = m->core->mainloop->io_new(m->core->mainloop, fd, PA_IO_EVENT_INPUT, sap_event_cb, u);
@ -706,9 +703,7 @@ int pa__init(pa_module*m) {
u->n_sessions = 0;
u->by_origin = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
pa_gettimeofday(&tv);
pa_timeval_add(&tv, DEATH_TIMEOUT * PA_USEC_PER_SEC);
u->check_death_event = m->core->mainloop->time_new(m->core->mainloop, &tv, check_death_event_cb, u);
u->check_death_event = pa_core_rttime_new(m->core, pa_rtclock_now() + DEATH_TIMEOUT * PA_USEC_PER_SEC, check_death_event_cb, u);
pa_modargs_free(ma);

View file

@ -31,6 +31,7 @@
#include <string.h>
#include <unistd.h>
#include <pulse/rtclock.h>
#include <pulse/timeval.h>
#include <pulse/util.h>
#include <pulse/xmalloc.h>
@ -77,7 +78,7 @@ PA_MODULE_USAGE(
#define DEFAULT_DESTINATION "224.0.0.56"
#define MEMBLOCKQ_MAXLENGTH (1024*170)
#define DEFAULT_MTU 1280
#define SAP_INTERVAL 5
#define SAP_INTERVAL (5*PA_USEC_PER_SEC)
static const char* const valid_modargs[] = {
"source",
@ -151,18 +152,14 @@ static void source_output_kill(pa_source_output* o) {
static void sap_event_cb(pa_mainloop_api *m, pa_time_event *t, const struct timeval *tv, void *userdata) {
struct userdata *u = userdata;
struct timeval next;
pa_assert(m);
pa_assert(t);
pa_assert(tv);
pa_assert(u);
pa_sap_send(&u->sap_context, 0);
pa_gettimeofday(&next);
pa_timeval_add(&next, SAP_INTERVAL * PA_USEC_PER_SEC);
m->time_restart(t, &next);
pa_core_rttime_restart(u->module->core, t, pa_rtclock_now() + SAP_INTERVAL);
}
int pa__init(pa_module*m) {
@ -186,7 +183,6 @@ int pa__init(pa_module*m) {
char *p;
int r, j;
socklen_t k;
struct timeval tv;
char hn[128], *n;
pa_bool_t loop = FALSE;
pa_source_output_new_data data;
@ -395,9 +391,7 @@ int pa__init(pa_module*m) {
pa_sap_send(&u->sap_context, 0);
pa_gettimeofday(&tv);
pa_timeval_add(&tv, SAP_INTERVAL * PA_USEC_PER_SEC);
u->sap_event = m->core->mainloop->time_new(m->core->mainloop, &tv, sap_event_cb, u);
u->sap_event = pa_core_rttime_new(m->core, pa_rtclock_now() + SAP_INTERVAL, sap_event_cb, u);
pa_source_output_put(u->source_output);

View file

@ -333,7 +333,7 @@ int pa_rtsp_connect(pa_rtsp_client *c) {
pa_xfree(c->session);
c->session = NULL;
if (!(c->sc = pa_socket_client_new_string(c->mainloop, c->hostname, c->port))) {
if (!(c->sc = pa_socket_client_new_string(c->mainloop, TRUE, c->hostname, c->port))) {
pa_log("failed to connect to server '%s:%d'", c->hostname, c->port);
return -1;
}