bigboard r7267 - trunk/applet



Author: otaylor
Date: Mon Mar 17 19:31:04 2008
New Revision: 7267
URL: http://svn.gnome.org/viewvc/bigboard?rev=7267&view=rev

Log:
Update to latest version of hippo-dbus-helper from libddm

Modified:
   trunk/applet/hippo-dbus-helper.c
   trunk/applet/hippo-dbus-helper.h

Modified: trunk/applet/hippo-dbus-helper.c
==============================================================================
--- trunk/applet/hippo-dbus-helper.c	(original)
+++ trunk/applet/hippo-dbus-helper.c	Mon Mar 17 19:31:04 2008
@@ -19,11 +19,14 @@
 } HippoDBusObject;
 
 typedef struct {
+    guint refcount;
+    DBusConnection *connection;
     char *well_known_name;
     char *owner;
     void *data;
     const HippoDBusServiceTracker *tracker;
     const HippoDBusSignalTracker  *signal_handlers;
+    guint removed : 1;
 } HippoDBusService;
 
 typedef struct {
@@ -665,8 +668,7 @@
                        member_name, member->in_args, dbus_message_get_signature(message));
         goto out;
     }
-
-    /* Object could be destroyed during this callback! */
+    
     reply = (* member->handler) (o->object, message, &derror);
 
     if (reply != NULL && dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
@@ -1064,7 +1066,8 @@
 }
 
 static HippoDBusService*
-service_new(const char                    *well_known_name,
+service_new(DBusConnection                *connection,
+            const char                    *well_known_name,
             const HippoDBusServiceTracker *tracker,
             const HippoDBusSignalTracker  *signal_handlers,
             void                          *data)
@@ -1072,6 +1075,8 @@
     HippoDBusService *service;
 
     service = g_new0(HippoDBusService, 1);
+    service->refcount = 1;
+    service->connection = connection;
     service->well_known_name = g_strdup(well_known_name);
     service->tracker = tracker;
     service->signal_handlers = signal_handlers;
@@ -1080,12 +1085,23 @@
     return service;
 }
 
+static HippoDBusService *
+service_ref(HippoDBusService *service)
+{
+    service->refcount++;
+
+    return service;
+}
+
 static void
-service_free(HippoDBusService *service)
+service_unref(HippoDBusService *service)
 {
-    g_free(service->well_known_name);
-    g_free(service->owner);
-    g_free(service);
+    service->refcount--;
+    if (service->refcount == 0) {
+        g_free(service->well_known_name);
+        g_free(service->owner);
+        g_free(service);
+    }
 }
 
 static void
@@ -1147,9 +1163,18 @@
 }
 
 static void
+on_startup_nonexistence(HippoDBusService *service)
+{
+    if (!service->removed)
+        (* service->tracker->unavailable_handler) (service->connection,
+                                                   service->well_known_name,
+                                                   NULL,
+                                                   service->data);
+}
+
+static void
 handle_name_owner_changed(DBusConnection *connection,
                           const char     *well_known_name,
-                          /* old and new may be NULL */
                           const char     *old_owner,
                           const char     *new_owner)
 {
@@ -1162,20 +1187,21 @@
     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);
+                owner ? owner : "");
+
         (* service->tracker->unavailable_handler) (connection,
                                                    service->well_known_name,
                                                    owner,
@@ -1201,33 +1227,30 @@
     }
 }
 
-typedef struct {
-    DBusConnection *connection;
-    char *well_known_name;
-    gboolean start_if_not_running;
-} GetOwnerData;
-
-static GetOwnerData*
-get_owner_data_new(DBusConnection *connection,
-                   const char     *well_known_name,
-                   gboolean        start_if_not_running)
-{
-    GetOwnerData *god;
-    god = g_new0(GetOwnerData, 1);
-    god->connection = connection;
-    god->well_known_name = g_strdup(well_known_name);
-    god->start_if_not_running = start_if_not_running;
-    dbus_connection_ref(connection);
-
-    return god;
-}
-
 static void
-get_owner_data_free(GetOwnerData *god)
+on_start_service_by_name_reply(DBusPendingCall *pending,
+                               void            *user_data)
 {
-    dbus_connection_unref(god->connection);
-    g_free(god->well_known_name);
-    g_free(god);
+    DBusMessage *reply;
+    HippoDBusService *service;
+
+    service = user_data;
+    
+    reply = dbus_pending_call_steal_reply(pending);
+    if (reply == NULL) {
+        g_warning("NULL reply in on_start_service_by_name_reply?");
+        return;
+    }
+    
+    if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
+        /* Just ignore, we'll get a NameOwnerChanged */
+    } else {
+        const char *message = "Unknown error";
+        dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &message, DBUS_TYPE_INVALID);
+        
+        g_warning("Initial activation of service '%s' failed: %s", service->well_known_name, message);
+        on_startup_nonexistence(service);        
+    }
 }
 
 static void
@@ -1235,9 +1258,9 @@
                    void            *user_data)
 {
     DBusMessage *reply;
-    GetOwnerData *god;
+    HippoDBusService *service;
 
-    god = user_data;
+    service = user_data;
     
     reply = dbus_pending_call_steal_reply(pending);
     if (reply == NULL) {
@@ -1250,41 +1273,67 @@
         if (!dbus_message_get_args(reply, NULL,
                                    DBUS_TYPE_STRING, &v_STRING,
                                    DBUS_TYPE_INVALID)) {
-            g_debug("GetNameOwner has wrong args '%s'",
-                    dbus_message_get_signature(reply));
+            g_warning("GetNameOwner has wrong args '%s'",
+                      dbus_message_get_signature(reply));
+            on_startup_nonexistence(service);
         } else {
-            g_debug("Got name owner '%s' for '%s'",
-                    v_STRING, god->well_known_name);
-            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,
+            handle_name_owner_changed(service->connection,
+                                      service->well_known_name,
                                       NULL,
                                       v_STRING);
+        }
+    } else  {
+        if (strcmp(dbus_message_get_error_name(reply),
+                   "org.freedesktop.DBus.Error.NameHasNoOwner") == 0) {
 
             /* One time on startup, we will start the service if
              * it's not running, which should lead to a notification.
              * We don't check the error though and just give up
              * if it fails.
              */
-            if (v_STRING == NULL && god->start_if_not_running) {
+            if ((service->tracker->flags & HIPPO_DBUS_SERVICE_START_IF_NOT_RUNNING) != 0) {
                 DBusMessage *msg;
                 dbus_uint32_t flags;
-                
+                DBusPendingCall *call;
+
                 msg = dbus_message_new_method_call (DBUS_SERVICE_DBUS,
                                                     DBUS_PATH_DBUS,
                                                     DBUS_INTERFACE_DBUS,
                                                     "StartServiceByName");
-
+                
                 flags = 0;
-                if (dbus_message_append_args (msg, DBUS_TYPE_STRING, &god->well_known_name,
-                                              DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID)) {
-                    dbus_connection_send(god->connection, msg, NULL);
+                if (!dbus_message_append_args (msg, DBUS_TYPE_STRING, &service->well_known_name,
+                                               DBUS_TYPE_UINT32, &flags, DBUS_TYPE_INVALID))
+                    g_error("out of memory");
+
+                call = NULL;
+                if (!dbus_connection_send_with_reply(service->connection, msg, &call, -1))
+                    g_error("out of memory");
+
+                /* Call == NULL means that we're already disconnected; in that case, we'll
+                 * omit any notification and assume that we're in some sort of
+                 * start-and-immediately-exit race.
+                 */
+                if (call != NULL) {
+                    if (!dbus_pending_call_set_notify(call, on_start_service_by_name_reply,
+                                                      service_ref(service),
+                                                      (DBusFreeFunction) service_unref))
+                        g_error("out of memory");
+
+                    /* rely on connection to hold a reference to it */
+                    dbus_pending_call_unref(call);
                 }
                 dbus_message_unref(msg);
+            } else {
+                on_startup_nonexistence(service);
             }
+            
+        } else {
+            const char *message = "Unknown error";
+        
+            dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &message, DBUS_TYPE_INVALID);
+            g_warning("GetNameOwner failed: %s", message);
+            on_startup_nonexistence(service);
         }
     }
     
@@ -1308,7 +1357,7 @@
     /* multiple registrations for the same name isn't allowed for now */
     g_return_if_fail(g_hash_table_lookup(helper->services_by_well_known, well_known_name) == NULL);
     
-    service = service_new(well_known_name, tracker, signal_handlers, data);
+    service = service_new(connection, well_known_name, tracker, signal_handlers, data);
 
     g_hash_table_replace(helper->services_by_well_known, service->well_known_name, service);
 
@@ -1328,23 +1377,24 @@
         g_error("out of memory");
     
     call = NULL;               
-    dbus_connection_send_with_reply(connection, get_owner, &call, -1);
+    if (!dbus_connection_send_with_reply(connection, get_owner, &call, -1))
+        g_error("out of memory");
+
+    /* Call == NULL means that we're already disconnected; in that case, we'll
+     * omit any notification and assume that we're in some sort of
+     * start-and-immediately-exit race.
+     */
     if (call != NULL) {
-        GetOwnerData *god;
-        
-        god = get_owner_data_new(connection, well_known_name,
-                                 (tracker->flags & HIPPO_DBUS_SERVICE_START_IF_NOT_RUNNING) != 0);
-        
         if (!dbus_pending_call_set_notify(call, on_get_owner_reply,
-                                          god,
-                                          (DBusFreeFunction) get_owner_data_free))
+                                          service_ref(service),
+                                          (DBusFreeFunction) service_unref))
             g_error("out of memory");
         
         /* rely on connection to hold a reference to it, if finalized
-         * I think on_get_song_props_reply won't get called though, 
-         * which is fine currently
+         * I think on_get_owner_reply won't get called. Again we just omit
+         * notification.
          */
-        dbus_pending_call_unref(call);        
+        dbus_pending_call_unref(call);
     }
 }
 
@@ -1365,6 +1415,8 @@
         g_warning("Multiple registered trackers for same service doesn't work yet");
         return;
     }
+
+    service->removed = TRUE;
     
     set_signal_handlers_matched(connection, well_known_name, service->signal_handlers, FALSE);
     set_owner_matched(connection, well_known_name, FALSE);
@@ -1380,7 +1432,7 @@
                                                    service->data);
     }
 
-    service_free(service);
+    service_unref(service);
 }
 
 static gboolean attempt_session_connect_timeout(void *data);
@@ -1779,11 +1831,7 @@
     if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL) {
         HippoDBusHelper *helper = get_helper(connection); 
         const char *sender = dbus_message_get_sender(message);
-        HippoDBusService *service;
-
-        service = NULL;
-        if (sender)
-            service = g_hash_table_lookup(helper->services_by_owner, sender);
+        HippoDBusService *service = g_hash_table_lookup(helper->services_by_owner, sender);
 
         if (service != NULL) {
             int i;
@@ -1828,6 +1876,7 @@
     char              *path;
     char              *interface;
     char              *method_prefix;
+    int                timeout;
 };
 
 HippoDBusProxy*
@@ -1846,11 +1895,19 @@
     proxy->bus_name = g_strdup(bus_name);
     proxy->path = g_strdup(path);
     proxy->interface = g_strdup(interface);
+    proxy->timeout = -1; /* Use default D-BUS value */
 
     return proxy;
 }
 
 void
+hippo_dbus_proxy_set_timeout(HippoDBusProxy *proxy,
+                             int             timeout_milliseconds)
+{
+    proxy->timeout = timeout_milliseconds;
+}
+
+void
 hippo_dbus_proxy_set_method_prefix(HippoDBusProxy *proxy,
                                    const char     *method_prefix)
 {
@@ -1917,7 +1974,7 @@
         }
     }
     
-    reply = dbus_connection_send_with_reply_and_block(proxy->connection, call, -1, error);
+    reply = dbus_connection_send_with_reply_and_block(proxy->connection, call, proxy->timeout, error);
     
     dbus_message_unref(call);
     
@@ -2115,7 +2172,7 @@
         DBusPendingCall *pending;
         
         pending = NULL;
-        dbus_connection_send_with_reply(proxy->connection, call, &pending, -1);
+        dbus_connection_send_with_reply(proxy->connection, call, &pending, proxy->timeout);
 
         if (pending == NULL) {
             g_warning("Failed to send method call %s (probably connection is disconnected)", method);

Modified: trunk/applet/hippo-dbus-helper.h
==============================================================================
--- trunk/applet/hippo-dbus-helper.h	(original)
+++ trunk/applet/hippo-dbus-helper.h	Mon Mar 17 19:31:04 2008
@@ -212,6 +212,10 @@
  */
 void              hippo_dbus_proxy_set_method_prefix       (HippoDBusProxy          *proxy,
                                                             const char              *method_prefix);
+/* Change the timeout from the default D-BUS value (25 seconds, as of D-BUS 1.3)
+ * -1 means use that default value */
+void              hippo_dbus_proxy_set_timeout             (HippoDBusProxy          *proxy,
+                                                            int                      timeout_milliseconds);
 void              hippo_dbus_proxy_unref                   (HippoDBusProxy          *proxy);
 
 DBusMessage* hippo_dbus_proxy_call_method_sync           (HippoDBusProxy        *proxy,



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