X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=avahi-common%2Fdbus-watch-glue.c;h=35e2b455c8202193d887943f4d43d86aa9b02419;hb=124c9f007617a5b4078a75843c6ee80f70186ed1;hp=11192f8fdbfd6cedc72db174e8a5ed596da1fdf3;hpb=7ada090e70d25937d27b2e93b0dab4d9d68c5d23;p=catta diff --git a/avahi-common/dbus-watch-glue.c b/avahi-common/dbus-watch-glue.c index 11192f8..35e2b45 100644 --- a/avahi-common/dbus-watch-glue.c +++ b/avahi-common/dbus-watch-glue.c @@ -19,11 +19,15 @@ USA. ***/ +#ifdef HAVE_CONFIG_H +#include +#endif + #include #include -#include - +#include "malloc.h" +#include "timeval.h" #include "dbus-watch-glue.h" static AvahiWatchEvent translate_dbus_to_avahi(unsigned int f) { @@ -81,13 +85,15 @@ static void connection_data_unref(ConnectionData *d) { } } -static void request_dispatch(ConnectionData *d) { +static void request_dispatch(ConnectionData *d, int enable) { static const struct timeval tv = { 0, 0 }; assert(d); - assert(dbus_connection_get_dispatch_status(d->connection) == DBUS_DISPATCH_DATA_REMAINS); - - d->poll_api->timeout_update(d->dispatch_timeout, &tv); + if (enable) { + assert(dbus_connection_get_dispatch_status(d->connection) == DBUS_DISPATCH_DATA_REMAINS); + d->poll_api->timeout_update(d->dispatch_timeout, &tv); + } else + d->poll_api->timeout_update(d->dispatch_timeout, NULL); } static void dispatch_timeout_callback(AvahiTimeout *t, void *userdata) { @@ -95,13 +101,22 @@ static void dispatch_timeout_callback(AvahiTimeout *t, void *userdata) { assert(t); assert(d); + connection_data_ref(d); + dbus_connection_ref(d->connection); + if (dbus_connection_dispatch(d->connection) == DBUS_DISPATCH_DATA_REMAINS) /* If there's still data, request that this handler is called again */ - request_dispatch(d); + request_dispatch(d, 1); + else + request_dispatch(d, 0); + + dbus_connection_unref(d->connection); + connection_data_unref(d); } -static void watch_callback(AvahiWatch *avahi_watch, int fd, AvahiWatchEvent events, void *userdata) { +static void watch_callback(AvahiWatch *avahi_watch, AVAHI_GCC_UNUSED int fd, AvahiWatchEvent events, void *userdata) { DBusWatch *dbus_watch = userdata; + assert(avahi_watch); assert(dbus_watch); @@ -123,7 +138,11 @@ static dbus_bool_t update_watch(const AvahiPoll *poll_api, DBusWatch *dbus_watch if (!(avahi_watch = poll_api->watch_new( poll_api, +#if (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR == 1 && DBUS_VERSION_MICRO >= 1) || (DBUS_VERSION_MAJOR == 1 && DBUS_VERSION_MINOR > 1) || (DBUS_VERSION_MAJOR > 1) + dbus_watch_get_unix_fd(dbus_watch), +#else dbus_watch_get_fd(dbus_watch), +#endif translate_dbus_to_avahi(dbus_watch_get_flags(dbus_watch)), watch_callback, dbus_watch))) @@ -180,10 +199,32 @@ typedef struct TimeoutData { const AvahiPoll *poll_api; AvahiTimeout *avahi_timeout; DBusTimeout *dbus_timeout; + int ref; } TimeoutData; +static TimeoutData* timeout_data_ref(TimeoutData *t) { + assert(t); + assert(t->ref >= 1); + + t->ref++; + return t; +} + +static void timeout_data_unref(TimeoutData *t) { + assert(t); + assert(t->ref >= 1); + + if (--t->ref <= 0) { + if (t->avahi_timeout) + t->poll_api->timeout_free(t->avahi_timeout); + + avahi_free(t); + } +} + static void update_timeout(TimeoutData *timeout) { assert(timeout); + assert(timeout->ref >= 1); if (dbus_timeout_get_enabled(timeout->dbus_timeout)) { struct timeval tv; @@ -201,10 +242,15 @@ static void timeout_callback(AvahiTimeout *avahi_timeout, void *userdata) { assert(avahi_timeout); assert(timeout); + timeout_data_ref(timeout); + dbus_timeout_handle(timeout->dbus_timeout); /* Ignore the return value */ + + if (timeout->avahi_timeout) + update_timeout(timeout); - update_timeout(timeout); + timeout_data_unref(timeout); } static dbus_bool_t add_timeout(DBusTimeout *dbus_timeout, void *userdata) { @@ -221,6 +267,7 @@ static dbus_bool_t add_timeout(DBusTimeout *dbus_timeout, void *userdata) { timeout->dbus_timeout = dbus_timeout; timeout->poll_api = d->poll_api; + timeout->ref = 1; if ((b = dbus_timeout_get_enabled(dbus_timeout))) avahi_elapse_time(&tv, dbus_timeout_get_interval(dbus_timeout), 0); @@ -229,12 +276,12 @@ static dbus_bool_t add_timeout(DBusTimeout *dbus_timeout, void *userdata) { d->poll_api, b ? &tv : NULL, timeout_callback, - dbus_timeout))) { + timeout))) { avahi_free(timeout); return FALSE; } - dbus_timeout_set_data(dbus_timeout, timeout, NULL); + dbus_timeout_set_data(dbus_timeout, timeout, (DBusFreeFunction) timeout_data_unref); return TRUE; } @@ -249,11 +296,10 @@ static void remove_timeout(DBusTimeout *dbus_timeout, void *userdata) { assert(timeout); d->poll_api->timeout_free(timeout->avahi_timeout); - avahi_free(timeout); - dbus_timeout_set_data(dbus_timeout, NULL, NULL); + timeout->avahi_timeout = NULL; } -static void timeout_toggled(DBusTimeout *dbus_timeout, void *userdata) { +static void timeout_toggled(DBusTimeout *dbus_timeout, AVAHI_GCC_UNUSED void *userdata) { TimeoutData *timeout; assert(dbus_timeout); @@ -263,11 +309,11 @@ static void timeout_toggled(DBusTimeout *dbus_timeout, void *userdata) { update_timeout(timeout); } -static void dispatch_status(DBusConnection *connection, DBusDispatchStatus new_status, void *userdata) { +static void dispatch_status(AVAHI_GCC_UNUSED DBusConnection *connection, DBusDispatchStatus new_status, void *userdata) { ConnectionData *d = userdata; if (new_status == DBUS_DISPATCH_DATA_REMAINS) - request_dispatch(d); + request_dispatch(d, 1); } int avahi_dbus_connection_glue(DBusConnection *c, const AvahiPoll *poll_api) { @@ -286,16 +332,16 @@ int avahi_dbus_connection_glue(DBusConnection *c, const AvahiPoll *poll_api) { if (!(d->dispatch_timeout = poll_api->timeout_new(poll_api, NULL, dispatch_timeout_callback, d))) goto fail; - if (!(dbus_connection_set_watch_functions(c, add_watch, remove_watch, watch_toggled, connection_data_ref(d), connection_data_unref))) + if (!(dbus_connection_set_watch_functions(c, add_watch, remove_watch, watch_toggled, connection_data_ref(d), (DBusFreeFunction)connection_data_unref))) goto fail; - if (!(dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, timeout_toggled, connection_data_ref(d), connection_data_unref))) + if (!(dbus_connection_set_timeout_functions(c, add_timeout, remove_timeout, timeout_toggled, connection_data_ref(d), (DBusFreeFunction)connection_data_unref))) goto fail; - dbus_connection_set_dispatch_status_function(c, dispatch_status, connection_data_ref(d), connection_data_unref); + dbus_connection_set_dispatch_status_function(c, dispatch_status, connection_data_ref(d), (DBusFreeFunction)connection_data_unref); if (dbus_connection_get_dispatch_status(c) == DBUS_DISPATCH_DATA_REMAINS) - request_dispatch(d); + request_dispatch(d, 1); connection_data_unref(d);