#include <stdarg.h>
-#include <pulse/xmalloc.h>
+#include <pulse/rtclock.h>
#include <pulse/timeval.h>
+#include <pulse/xmalloc.h>
+
+#include <pulsecore/core-rtclock.h>
+#include <pulsecore/core-util.h>
#include <pulsecore/log.h>
#include "dbus-util.h"
pa_mainloop_api *mainloop;
DBusConnection *connection;
pa_defer_event* dispatch_event;
+ pa_bool_t use_rtclock:1;
+};
+
+struct timeout_data {
+ pa_dbus_wrap_connection *c;
+ DBusTimeout *timeout;
};
static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) {
}
/* pa_time_event_cb_t timer event handler */
-static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struct timeval *tv, void *userdata) {
- DBusTimeout *timeout = userdata;
+static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struct timeval *t, void *userdata) {
+ struct timeval tv;
+ struct timeout_data *d = userdata;
- if (dbus_timeout_get_enabled(timeout)) {
- struct timeval next = *tv;
- dbus_timeout_handle(timeout);
+ pa_assert(d);
+ pa_assert(d->c);
+
+ if (dbus_timeout_get_enabled(d->timeout)) {
+ dbus_timeout_handle(d->timeout);
/* restart it for the next scheduled time */
- pa_timeval_add(&next, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
- ea->time_restart(e, &next);
+ ea->time_restart(e, pa_timeval_rtstore(&tv, pa_timeval_load(t) + dbus_timeout_get_interval(d->timeout) * PA_USEC_PER_MSEC, d->c->use_rtclock));
}
}
c->mainloop->io_enable(ev, get_watch_flags(watch));
}
+static void time_event_destroy_cb(pa_mainloop_api *a, pa_time_event *e, void *userdata) {
+ pa_xfree(userdata);
+}
+
/* DBusAddTimeoutFunction callback for pa mainloop */
static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {
pa_dbus_wrap_connection *c = data;
pa_time_event *ev;
struct timeval tv;
+ struct timeout_data *d;
pa_assert(timeout);
pa_assert(c);
if (!dbus_timeout_get_enabled(timeout))
return FALSE;
- pa_gettimeofday(&tv);
- pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
-
- ev = c->mainloop->time_new(c->mainloop, &tv, handle_time_event, timeout);
+ d = pa_xnew(struct timeout_data, 1);
+ d->c = c;
+ d->timeout = timeout;
+ ev = c->mainloop->time_new(c->mainloop, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, c->use_rtclock), handle_time_event, d);
+ c->mainloop->time_set_destroy(ev, time_event_destroy_cb);
dbus_timeout_set_data(timeout, ev, NULL);
/* DBusTimeoutToggledFunction callback for pa mainloop */
static void toggle_timeout(DBusTimeout *timeout, void *data) {
- pa_dbus_wrap_connection *c = data;
+ struct timeout_data *d = data;
pa_time_event *ev;
+ struct timeval tv;
+ pa_assert(d);
+ pa_assert(d->c);
pa_assert(timeout);
- pa_assert(c);
pa_assert_se(ev = dbus_timeout_get_data(timeout));
if (dbus_timeout_get_enabled(timeout)) {
- struct timeval tv;
-
- pa_gettimeofday(&tv);
- pa_timeval_add(&tv, (pa_usec_t) dbus_timeout_get_interval(timeout) * 1000);
-
- c->mainloop->time_restart(ev, &tv);
+ d->c->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, d->c->use_rtclock));
} else
- c->mainloop->time_restart(ev, NULL);
+ d->c->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, PA_USEC_INVALID, d->c->use_rtclock));
}
static void wakeup_main(void *userdata) {
c->mainloop->defer_enable(c->dispatch_event, 1);
}
-pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, DBusBusType type, DBusError *error) {
+pa_dbus_wrap_connection* pa_dbus_wrap_connection_new(pa_mainloop_api *m, pa_bool_t use_rtclock, DBusBusType type, DBusError *error) {
DBusConnection *conn;
- pa_dbus_wrap_connection *pconn = NULL;
+ pa_dbus_wrap_connection *pconn;
+ char *id;
pa_assert(type == DBUS_BUS_SYSTEM || type == DBUS_BUS_SESSION || type == DBUS_BUS_STARTER);
pconn = pa_xnew(pa_dbus_wrap_connection, 1);
pconn->mainloop = m;
pconn->connection = conn;
+ pconn->use_rtclock = use_rtclock;
dbus_connection_set_exit_on_disconnect(conn, FALSE);
dbus_connection_set_dispatch_status_function(conn, dispatch_status, pconn, NULL);
pconn->dispatch_event = pconn->mainloop->defer_new(pconn->mainloop, dispatch_cb, conn);
+ pa_log_debug("Successfully connected to D-Bus %s bus %s as %s",
+ type == DBUS_BUS_SYSTEM ? "system" : (type == DBUS_BUS_SESSION ? "session" : "starter"),
+ pa_strnull((id = dbus_connection_get_server_id(conn))),
+ pa_strnull(dbus_bus_get_unique_name(conn)));
+
+ dbus_free(id);
+
return pconn;
}
dbus_connection_close(c->connection);
/* must process remaining messages, bit of a kludge to handle
* both unload and shutdown */
- while (dbus_connection_read_write_dispatch(c->connection, -1));
+ while (dbus_connection_read_write_dispatch(c->connection, -1))
+ ;
}
c->mainloop->defer_free(c->dispatch_event);
void pa_dbus_pending_free(pa_dbus_pending *p) {
pa_assert(p);
- if (p->pending)
- dbus_pending_call_cancel(p->pending); /* p->pending is freed by cancel() */
+ if (p->pending) {
+ dbus_pending_call_cancel(p->pending);
+ dbus_pending_call_unref(p->pending);
+ }
if (p->message)
dbus_message_unref(p->message);