gvfs r1704 - in trunk: . client



Author: alexl
Date: Mon Mar 31 10:38:43 2008
New Revision: 1704
URL: http://svn.gnome.org/viewvc/gvfs?rev=1704&view=rev

Log:
2008-03-31  Alexander Larsson  <alexl redhat com>

        * client/gvfsdaemondbus.[ch]:
	In call_sync, on stale cache errors due to a
	mount daemon disappearing, invalidate caches and
	return G_VFS_ERROR_RETRY so that the caller can
	retry with fresh caches.
	
        * client/gdaemonfile.c:
	Retry calls on G_VFS_ERROR_RETRY.




Modified:
   trunk/ChangeLog
   trunk/client/gdaemonfile.c
   trunk/client/gvfsdaemondbus.c
   trunk/client/gvfsdaemondbus.h

Modified: trunk/client/gdaemonfile.c
==============================================================================
--- trunk/client/gdaemonfile.c	(original)
+++ trunk/client/gdaemonfile.c	Mon Mar 31 10:38:43 2008
@@ -398,7 +398,10 @@
 {
   DBusMessage *message, *reply;
   va_list var_args;
+  GError *my_error;
 
+ retry:
+  
   message = create_empty_message (file, op, mount_info_out, error);
   if (!message)
     return NULL;
@@ -409,12 +412,24 @@
 				      var_args);
   va_end (var_args);
 
+
+  my_error = NULL;
   reply = _g_vfs_daemon_call_sync (message,
 				   connection_out,
 				   NULL, NULL, NULL,
-				   cancellable, error);
+				   cancellable, &my_error);
   dbus_message_unref (message);
 
+  if (reply == NULL)
+    {
+      if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
+	{
+	  g_error_free (my_error);
+	  goto retry;
+	}
+      g_propagate_error (error, my_error);
+    }
+
   return reply;
 }
 
@@ -437,7 +452,10 @@
   GMountInfo *mount_info1, *mount_info2;
   const char *path1, *path2;
   va_list var_args;
+  GError *my_error;
 
+ retry:
+  
   mount_info1 = _g_daemon_vfs_get_mount_info_sync (daemon_file1->mount_spec,
 						   daemon_file1->path,
 						   error);
@@ -488,18 +506,29 @@
 				      first_arg_type,
 				      var_args);
   va_end (var_args);
-  
+
+  my_error = NULL;
   reply = _g_vfs_daemon_call_sync (message,
 				   connection_out,
 				   callback_obj_path,
 				   callback,
 				   callback_user_data, 
-				   cancellable, error);
+				   cancellable, &my_error);
   dbus_message_unref (message);
 
   g_mount_info_unref (mount_info1);
   if (mount_info2)
     g_mount_info_unref (mount_info2);
+
+  if (reply == NULL)
+    {
+      if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
+	{
+	  g_error_free (my_error);
+	  goto retry;
+	}
+      g_propagate_error (error, my_error);
+    }
   
   return reply;
 }
@@ -1840,7 +1869,10 @@
   DBusMessage *message, *reply;
   DBusMessageIter iter;
   dbus_uint32_t flags_dbus;
+  GError *my_error;
 
+ retry:
+  
   message = create_empty_message (file, G_VFS_DBUS_MOUNT_OP_SET_ATTRIBUTE, NULL, error);
   if (!message)
     return FALSE;
@@ -1854,13 +1886,22 @@
 
   _g_dbus_append_file_attribute (&iter, attribute, type, value_p);
 
+  my_error = NULL;
   reply = _g_vfs_daemon_call_sync (message,
 				   NULL,
 				   NULL, NULL, NULL,
-				   cancellable, error);
+				   cancellable, &my_error);
 
   if (reply == NULL)
-    return FALSE;
+    {
+      if (g_error_matches (my_error, G_VFS_ERROR, G_VFS_ERROR_RETRY))
+	{
+	  g_error_free (my_error);
+	  goto retry;
+	}
+      g_propagate_error (error, my_error);
+      return FALSE;
+    }
 
   dbus_message_unref (reply);
   return TRUE;

Modified: trunk/client/gvfsdaemondbus.c
==============================================================================
--- trunk/client/gvfsdaemondbus.c	(original)
+++ trunk/client/gvfsdaemondbus.c	Mon Mar 31 10:38:43 2008
@@ -65,6 +65,15 @@
 G_LOCK_DEFINE_STATIC(obj_path_map);
 
 static void setup_async_fd_receive (VfsConnectionData *connection_data);
+static void invalidate_local_connection (const char *dbus_id,
+					 GError **error);
+  
+
+GQuark
+_g_vfs_error_quark (void)
+{
+  return g_quark_from_static_string ("g-vfs-error-quark");
+}
 
 static gpointer
 vfs_dbus_init (gpointer arg)
@@ -690,9 +699,6 @@
   if (connection == NULL)
     return NULL;
 
-  /* TODO: Handle errors below due to unmount and invalidate the
-     sync connection cache */
-  
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     return NULL;
 
@@ -715,11 +721,12 @@
 					    G_VFS_DBUS_TIMEOUT_MSECS))
 	_g_dbus_oom ();
       
-      if (pending == NULL)
+      if (pending == NULL ||
+	  !dbus_connection_get_is_connected (connection))
 	{
-	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
-		       "Error while getting peer-to-peer dbus connection: %s",
-		       "Connection is closed");
+	  if (pending)
+	    dbus_pending_call_unref (pending);
+	  invalidate_local_connection (dbus_id, error);
 	  goto out;
 	}
 
@@ -804,7 +811,17 @@
 							 &derror);
       if (!reply)
 	{
-	  _g_error_from_dbus (&derror, error);
+	  if (dbus_error_has_name (&derror, DBUS_ERROR_NO_REPLY) &&
+	      !dbus_connection_get_is_connected (connection))
+	    {
+	      /* The mount for this connection died, we invalidate
+	       * the caches, and then caller needs to retry.
+	       */
+
+	      invalidate_local_connection (dbus_id, error);
+	    }
+	  else
+	    _g_error_from_dbus (&derror, error);
 	  dbus_error_free (&derror);
 	  goto out;
 	}
@@ -852,6 +869,24 @@
   g_free (local);
 }
 
+static void
+invalidate_local_connection (const char *dbus_id,
+			     GError **error)
+{
+  ThreadLocalConnections *local;
+  
+  _g_daemon_vfs_invalidate_dbus_id (dbus_id);
+
+  local = g_static_private_get (&local_connections);
+  if (local)
+    g_hash_table_remove (local->connections, dbus_id);
+  
+  g_set_error (error,
+	       G_VFS_ERROR,
+	       G_VFS_ERROR_RETRY,
+	       "Cache invalid, retry (internally handled)");
+}
+
 DBusConnection *
 _g_dbus_connection_get_sync (const char *dbus_id,
 			     GError **error)
@@ -877,20 +912,38 @@
     }
 
   if (dbus_id == NULL)
-    connection = local->session_bus;
+    {
+      /* Session bus */
+      
+      if (local->session_bus)
+	{
+	  if (dbus_connection_get_is_connected (local->session_bus))
+	    return local->session_bus;
+
+	  /* Session bus was disconnected, re-connect */
+	  local->session_bus = NULL;
+	  dbus_connection_unref (local->session_bus);
+	}
+    }
   else
-    connection = g_hash_table_lookup (local->connections, dbus_id);
-  
-  if (connection != NULL)
     {
-      if (!dbus_connection_get_is_connected (connection))
+      /* Mount daemon connection */
+      
+      connection = g_hash_table_lookup (local->connections, dbus_id);
+      if (connection != NULL)
 	{
-	  _g_daemon_vfs_invalidate_dbus_id (dbus_id);
-	  g_hash_table_remove (local->connections, dbus_id);
-	  return NULL;
+	  if (!dbus_connection_get_is_connected (connection))
+	    {
+	      /* The mount for this connection died, we invalidate
+	       * the caches, and then caller needs to retry.
+	       */
+
+	      invalidate_local_connection (dbus_id, error);
+	      return NULL;
+	    }
+	  
+	  return connection;
 	}
-      else
-	return connection;
     }
 
   dbus_error_init (&derror);
@@ -910,7 +963,7 @@
       local->session_bus = bus;
 
       if (dbus_id == NULL)
-	return bus;
+	return bus; /* We actually wanted the session bus, so done */
     }
   
   message = dbus_message_new_method_call (dbus_id,

Modified: trunk/client/gvfsdaemondbus.h
==============================================================================
--- trunk/client/gvfsdaemondbus.h	(original)
+++ trunk/client/gvfsdaemondbus.h	Mon Mar 31 10:38:43 2008
@@ -29,6 +29,16 @@
 
 G_BEGIN_DECLS
 
+/* Used for internal errors */
+GQuark  _g_vfs_error_quark (void);
+#define G_VFS_ERROR _g_vfs_error_quark()
+
+typedef enum
+{
+  G_VFS_ERROR_RETRY
+} GVfsError;
+
+
 typedef void (*GVfsAsyncDBusCallback) (DBusMessage *reply,
 				       DBusConnection *connection,
 				       GError *io_error,



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