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