HippoDBusServiceTracker - unavailable on startup



Right now with HippoDBusServiceTracker if the service isn't available on
startup, then you get no callbacks at all until it is available.

That covers the use case where your fallback is "do nothing", but if you
have a concrete fallback action, then you'd rather:

 - Check for availability on startup
 - If the service is not there do the fallback
 - Otherwise do the action using the service

(In particular, when the data model engine isn't there and can't be
activated, I want to the data model to immediately signal "ready")

The attached patch caters to this by calling the 'unavailable' handler
of HippoDBusServiceTracker with a NULL unique name on startup if the
service isn't running.

This approach:

 - Is slightly incompatible with any existing uses of
    HippoDBusServiceTracker, which would need to be audited.
 - Avoids adding another callback to the vtable

Other approaches are possible, especially if HippoDBusServiceTracker
was actually a tracker object rather than a couple of functions and a
callback vtable.

The patch also fixes some confusion about what GetNameOwner does when
there is no owner ... it throws an error.

- Owen

Index: hippo-dbus-helper.c
===================================================================
--- hippo-dbus-helper.c	(revision 6865)
+++ hippo-dbus-helper.c	(working copy)
@@ -1145,20 +1145,26 @@
     if (service == NULL)
         return; /* we don't care about this */
 
-    if (service->owner &&
-        (new_owner == NULL ||
-         strcmp(service->owner, new_owner) != 0)) {
-        /* Our previously-believed owner is going away */
+    if ((new_owner == NULL ||
+         (service->owner != NULL && strcmp(service->owner, new_owner) != 0))) {
+        /* Our previously-believed owner is going away, or we didn't find
+         * the service on startup. */
         char *owner;
-        
-        g_hash_table_remove(helper->services_by_owner,
-                            service->owner);
-        owner = service->owner;
-        service->owner = NULL;
 
-        g_debug("Service '%s' is now unavailable, old owner was '%s'",
-                service->well_known_name,
-                owner);
+        if (service->owner) {
+            g_hash_table_remove(helper->services_by_owner,
+                                service->owner);
+            owner = service->owner;
+            service->owner = NULL;
+            
+            g_debug("Service '%s' is now unavailable, old owner was '%s'",
+                    service->well_known_name,
+                    owner);
+        } else {
+            g_debug("Service '%s' not available on startup",
+                    service->well_known_name);
+        }
+
         (* service->tracker->unavailable_handler) (connection,
                                                    service->well_known_name,
                                                    owner,
@@ -1241,7 +1247,6 @@
             if (*v_STRING == '\0')
                 v_STRING = NULL;
 
-            /* this will do nothing if going NULL->NULL on startup */
             handle_name_owner_changed(god->connection,
                                       god->well_known_name,
                                       NULL,
@@ -1269,6 +1274,19 @@
                 dbus_message_unref(msg);
             }
         }
+    } else  {
+        /*
+         * Probably org.freedesktop.DBus.Error.NameHasNoOwner, but we might as well treat
+         * all error messages the same.
+         */
+        const char *message = NULL;
+        dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &message, DBUS_TYPE_INVALID);
+        g_debug("GetNameOwner failed: %s", message);
+        
+        handle_name_owner_changed(god->connection,
+                                  god->well_known_name,
+                                  NULL,
+                                  NULL);
     }
     
     dbus_message_unref(reply);

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]