X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/efdd3d054ba8ace4560dfe9008ac931966b88249..bbed792cdf6fe823837aaa0f5dcefcf4f5ac1917:/src/modules/reserve-monitor.c diff --git a/src/modules/reserve-monitor.c b/src/modules/reserve-monitor.c index 13ecde2b..70de870a 100644 --- a/src/modules/reserve-monitor.c +++ b/src/modules/reserve-monitor.c @@ -32,12 +32,14 @@ #include #include "reserve-monitor.h" +#include "reserve.h" struct rm_monitor { int ref; char *device_name; char *service_name; + char *match; DBusConnection *connection; @@ -51,12 +53,35 @@ struct rm_monitor { #define SERVICE_PREFIX "org.freedesktop.ReserveDevice1." +#define SERVICE_FILTER \ + "type='signal'," \ + "sender='" DBUS_SERVICE_DBUS "'," \ + "interface='" DBUS_INTERFACE_DBUS "'," \ + "member='NameOwnerChanged'," \ + "arg0='%s'" + +static unsigned get_busy( + DBusConnection *c, + const char *name_owner) { + + const char *un; + + if (!name_owner || !*name_owner) + return FALSE; + + /* If we ourselves own the device, then don't consider this 'busy' */ + if ((un = dbus_bus_get_unique_name(c))) + if (strcmp(name_owner, un) == 0) + return FALSE; + + return TRUE; +} + static DBusHandlerResult filter_handler( DBusConnection *c, DBusMessage *s, void *userdata) { - DBusMessage *reply; rm_monitor *m; DBusError error; @@ -78,18 +103,11 @@ static DBusHandlerResult filter_handler( goto invalid; if (strcmp(name, m->service_name) == 0) { - m->busy = !!(new && *new); + unsigned old_busy = m->busy; - /* If we ourselves own the device, then don't consider this 'busy' */ - if (m->busy) { - const char *un; + m->busy = get_busy(c, new); - if ((un = dbus_bus_get_unique_name(c))) - if (strcmp(new, un) == 0) - m->busy = FALSE; - } - - if (m->change_cb) { + if (m->busy != old_busy && m->change_cb) { m->ref++; m->change_cb(m); rm_release(m); @@ -97,41 +115,21 @@ static DBusHandlerResult filter_handler( } } - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - invalid: - if (!(reply = dbus_message_new_error( - s, - DBUS_ERROR_INVALID_ARGS, - "Invalid arguments"))) - goto oom; - - if (!dbus_connection_send(c, reply, NULL)) - goto oom; - - dbus_message_unref(reply); - dbus_error_free(&error); - return DBUS_HANDLER_RESULT_HANDLED; - -oom: - if (reply) - dbus_message_unref(reply); - - dbus_error_free(&error); - - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } int rm_watch( rm_monitor **_m, DBusConnection *connection, - const char*device_name, + const char *device_name, rm_change_cb_t change_cb, DBusError *error) { rm_monitor *m = NULL; + char *name_owner; int r; DBusError _error; @@ -175,11 +173,13 @@ int rm_watch( m->filtering = 1; - dbus_bus_add_match(m->connection, - "type='signal'," - "sender='" DBUS_SERVICE_DBUS "'," - "interface='" DBUS_INTERFACE_DBUS "'," - "member='NameOwnerChanged'", error); + if (!(m->match = malloc(sizeof(SERVICE_FILTER) - 2 + strlen(m->service_name)))) { + r = -ENOMEM; + goto fail; + } + + sprintf(m->match, SERVICE_FILTER, m->service_name); + dbus_bus_add_match(m->connection, m->match, error); if (dbus_error_is_set(error)) { r = -EIO; @@ -188,12 +188,11 @@ int rm_watch( m->matching = 1; - m->busy = dbus_bus_name_has_owner(m->connection, m->service_name, error); - - if (dbus_error_is_set(error)) { - r = -EIO; + if ((r = rd_dbus_get_name_owner(m->connection, m->service_name, &name_owner, error)) < 0) goto fail; - } + + m->busy = get_busy(m->connection, name_owner); + free(name_owner); *_m = m; return 0; @@ -220,10 +219,8 @@ void rm_release(rm_monitor *m) { if (m->matching) dbus_bus_remove_match( m->connection, - "type='signal'," - "sender='" DBUS_SERVICE_DBUS "'," - "interface='" DBUS_INTERFACE_DBUS "'," - "member='NameOwnerChanged'", NULL); + m->match, + NULL); if (m->filtering) dbus_connection_remove_filter( @@ -233,6 +230,7 @@ void rm_release(rm_monitor *m) { free(m->device_name); free(m->service_name); + free(m->match); if (m->connection) dbus_connection_unref(m->connection);