[registry] Send a ping to a process when marking as hung
authorMike Gorse <mgorse@suse.com>
Wed, 14 Mar 2012 20:55:46 +0000 (15:55 -0500)
committerMike Gorse <mgorse@suse.com>
Wed, 14 Mar 2012 21:07:57 +0000 (16:07 -0500)
Sometimes keys that should be captured by event listeners are instead
passed through to the application. It seems that at-spi2-registryd might
not always be removing the process from the list of hung processes. I
have not reproduced this recently, and I'm not sure where the root
problem is. Hoping that it will help to send the process a ping and use
the reply as a queue that it is un-hung (previously we were relying on
receiving a reply to the original key event notification).

https://bugzilla.gnome.org/show_bug.cgi?id=671976

registryd/deviceeventcontroller.c

index 93ee40d..66feaad 100644 (file)
@@ -1178,6 +1178,25 @@ time_elapsed (struct timeval *origin)
   return (tv.tv_sec - origin->tv_sec) * 1000 + (tv.tv_usec - origin->tv_usec) / 1000;
 }
 
+static void
+reset_hung_process_from_ping (DBusPendingCall *pending, void *data)
+{
+  gchar *bus_name = data;
+  GSList *l;
+
+  for (l = hung_processes; l; l = l->next)
+  {
+    if (!strcmp (l->data, data))
+    {
+      g_free (l->data);
+      hung_processes = g_slist_remove (hung_processes, data);
+      break;
+    }
+  }
+  g_free (data);
+  dbus_pending_call_unref (pending);
+}
+
 static DBusMessage *
 send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout, DBusError *error)
 {
@@ -1198,9 +1217,22 @@ send_and_allow_reentry (DBusConnection *bus, DBusMessage *message, int timeout,
       {
         const char *dest = dbus_message_get_destination (message);
         GSList *l;
+        gchar *bus_name_dup;
         dbus_message_ref (message);
         dbus_pending_call_set_notify (pending, reset_hung_process, message,
                                       (DBusFreeFunction) dbus_message_unref);
+        message = dbus_message_new_method_call (dest, "/",
+                                                "org.freedesktop.DBus.Peer",
+                                                "Ping");
+        if (!message)
+          return;
+        dbus_connection_send_with_reply (bus, message, &pending, -1);
+        dbus_message_unref (message);
+        if (!pending)
+          return;
+        bus_name_dup = g_strdup (dest);
+        dbus_pending_call_set_notify (pending, reset_hung_process_from_ping,
+                                      bus_name_dup, NULL);
         for (l = hung_processes; l; l = l->next)
           if (!strcmp (l->data, dest))
             return NULL;