]> code.delx.au - pulseaudio/blobdiff - src/modules/reserve-monitor.c
Merge remote branch 'tanuk/dbus-work'
[pulseaudio] / src / modules / reserve-monitor.c
index 64d2a7cc4e575310a488f70e12070ecf045c0f12..ab453e61aaa50c215be2ecb44945f20f9f0160c1 100644 (file)
@@ -1,3 +1,5 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: t -*-*/
+
 /***
   Copyright 2009 Lennart Poettering
 
@@ -36,6 +38,7 @@ struct rm_monitor {
 
        char *device_name;
        char *service_name;
+       char *match;
 
        DBusConnection *connection;
 
@@ -49,12 +52,18 @@ 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 DBusHandlerResult filter_handler(
        DBusConnection *c,
        DBusMessage *s,
        void *userdata) {
 
-       DBusMessage *reply;
        rm_monitor *m;
        DBusError error;
 
@@ -76,9 +85,17 @@ static DBusHandlerResult filter_handler(
                        goto invalid;
 
                if (strcmp(name, m->service_name) == 0) {
-
                        m->busy = !!(new && *new);
 
+                       /* If we ourselves own the device, then don't consider this 'busy' */
+                       if (m->busy) {
+                               const char *un;
+
+                               if ((un = dbus_bus_get_unique_name(c)))
+                                       if (strcmp(new, un) == 0)
+                                               m->busy = FALSE;
+                       }
+
                        if (m->change_cb) {
                                m->ref++;
                                m->change_cb(m);
@@ -87,31 +104,10 @@ 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(
@@ -165,11 +161,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;
@@ -210,10 +208,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(
@@ -223,6 +219,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);