[patch] improve dbus disconnect handling (bug 369214, maybe 364864)



Hi,

A while ago I noticed that gnome-vfs applications tend to crash when
they get disconnected from the gnome-vfs daemon (if the daemon crashes, 
for example).  This patch fixes a few issues in
gnome-vfs-daemon-method.c:execute_operation():

- if dbus_connection_send_with_reply fails, the cancellation ID doesn't
  get cleaned up.
- if the connection dies, the while (!dbus_pending_call_get_completed())
  loop exits, but no reply is available; the connection needs to be
  cleaned up, but I'm not sure what further error recovery is possible.

>From my testing at the time, this at least stopped applications from
crashing when the daemon died.  I'm not sure exactly what happened
afterwards, but I think the application did tend to recover after
suffering several errors.

enjoy,
-jonathan
Index: libgnomevfs/gnome-vfs-daemon-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-daemon-method.c,v
retrieving revision 1.13
diff -u -p -u -p -r1.13 gnome-vfs-daemon-method.c
--- libgnomevfs/gnome-vfs-daemon-method.c	20 Nov 2006 12:55:33 -0000	1.13
+++ libgnomevfs/gnome-vfs-daemon-method.c	23 Nov 2006 13:48:15 -0000
@@ -353,6 +353,12 @@ destroy_private_connection (gpointer dat
 	g_free (ret);
 }
 
+static void
+private_connection_died (LocalConnection *connection)
+{
+	g_static_private_set (&local_connection_private, NULL, NULL);
+}
+
 static LocalConnection *
 get_private_connection ()
 {
@@ -627,7 +633,8 @@ execute_operation (const gchar      *met
 					      message, &pending_call, timeout)) {
 		dbus_message_unref (message);
 		*result = GNOME_VFS_ERROR_INTERNAL;
-		return NULL;
+		reply = NULL;
+		goto out;
 	}
 
 	dbus_message_unref (message);
@@ -636,23 +643,22 @@ execute_operation (const gchar      *met
 	       dbus_connection_read_write_dispatch (connection->connection, -1))
 		;
 
+	if (!dbus_connection_get_is_connected (connection->connection)) {
+		private_connection_died (connection);
+		*result = GNOME_VFS_ERROR_INTERNAL;
+		reply = NULL;
+		goto out;
+	}
 	reply = dbus_pending_call_steal_reply (pending_call);
 
 	dbus_pending_call_unref (pending_call);
 	
+	if (result) {
+		*result = (reply == NULL) ? GNOME_VFS_ERROR_TIMEOUT : GNOME_VFS_OK;
+	}
+ out:
 	if (cancellation_id != -1) {
 		cancellation_id_free (cancellation_id, context);
-	}
-
-	if (reply == NULL) {
-		if (result) {
-			*result = GNOME_VFS_ERROR_TIMEOUT;
-		}
-		return NULL;
-	}
-
-	if (result) {
-		*result = GNOME_VFS_OK;
 	}
 
 	return reply;


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