diff options
| author | Lennart Poettering <lennart@poettering.net> | 2010-02-16 02:49:44 +0100 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2010-02-21 17:47:36 +0100 | 
| commit | ac76dbde6312b8052b80ce0239ef9443cfb27e1f (patch) | |
| tree | 42ecc9a1907b049798da5b3f4b69b13feae6d924 | |
| parent | 69ddfaf6ed8db98535382413ec4675865053dbc2 (diff) | |
dbus: first restart timer, then dispatch it
This makes sure that we don't access the timer after it might have been
destroyed already from the dbus timeout callback.
https://bugzilla.redhat.com/attachment.cgi?id=389952
| -rw-r--r-- | src/pulsecore/dbus-util.c | 29 | 
1 files changed, 16 insertions, 13 deletions
diff --git a/src/pulsecore/dbus-util.c b/src/pulsecore/dbus-util.c index e3700ea5..09ab071b 100644 --- a/src/pulsecore/dbus-util.c +++ b/src/pulsecore/dbus-util.c @@ -45,17 +45,16 @@ struct pa_dbus_wrap_connection {  };  struct timeout_data { -    pa_dbus_wrap_connection *c; +    pa_dbus_wrap_connection *connection;      DBusTimeout *timeout;  };  static void dispatch_cb(pa_mainloop_api *ea, pa_defer_event *ev, void *userdata) {      DBusConnection *conn = userdata; -    if (dbus_connection_dispatch(conn) == DBUS_DISPATCH_COMPLETE) { +    if (dbus_connection_dispatch(conn) == DBUS_DISPATCH_COMPLETE)          /* no more data to process, disable the deferred */          ea->defer_enable(ev, 0); -    }  }  /* DBusDispatchStatusFunction callback for the pa mainloop */ @@ -132,13 +131,17 @@ static void handle_time_event(pa_mainloop_api *ea, pa_time_event* e, const struc      struct timeout_data *d = userdata;      pa_assert(d); -    pa_assert(d->c); +    pa_assert(d->connection);      if (dbus_timeout_get_enabled(d->timeout)) { -        dbus_timeout_handle(d->timeout); +        /* Restart it for the next scheduled time. We do this before +         * calling dbus_timeout_handle() to make sure that the time +         * event is still around. */ +        ea->time_restart(e, pa_timeval_rtstore(&tv, +                                               pa_timeval_load(t) + dbus_timeout_get_interval(d->timeout) * PA_USEC_PER_MSEC, +                                               d->connection->use_rtclock)); -        /* restart it for the next scheduled time */ -        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)); +        dbus_timeout_handle(d->timeout);      }  } @@ -208,7 +211,7 @@ static dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) {          return FALSE;      d = pa_xnew(struct timeout_data, 1); -    d->c = c; +    d->connection = 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); @@ -237,15 +240,15 @@ static void toggle_timeout(DBusTimeout *timeout, void *data) {      struct timeval tv;      pa_assert(d); -    pa_assert(d->c); +    pa_assert(d->connection);      pa_assert(timeout);      pa_assert_se(ev = dbus_timeout_get_data(timeout)); -    if (dbus_timeout_get_enabled(timeout)) { -        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 -        d->c->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, PA_USEC_INVALID, d->c->use_rtclock)); +    if (dbus_timeout_get_enabled(timeout)) +        d->connection->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, pa_rtclock_now() + dbus_timeout_get_interval(timeout) * PA_USEC_PER_MSEC, d->connection->use_rtclock)); +    else +        d->connection->mainloop->time_restart(ev, pa_timeval_rtstore(&tv, PA_USEC_INVALID, d->connection->use_rtclock));  }  static void wakeup_main(void *userdata) {  | 
