summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2008-03-31 09:39:48 +0000
committerAlexander Larsson <alexl@src.gnome.org>2008-03-31 09:39:48 +0000
commit99f716aa0647980dad4b076cf4f5bb7f1debc1a1 (patch)
tree15c7f5643404cfeeb2179309f0d5cdc0ff0967d3
parent1371cc7f64786e3d005a54e66f4f628995d9dadd (diff)
downloadgvfs-99f716aa0647980dad4b076cf4f5bb7f1debc1a1.tar.gz
In call_sync, on stale cache errors due to a mount daemon disappearing,
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. svn path=/branches/gnome-2-22/; revision=1705
-rw-r--r--ChangeLog11
-rw-r--r--client/gdaemonfile.c51
-rw-r--r--client/gvfsdaemondbus.c91
-rw-r--r--client/gvfsdaemondbus.h10
4 files changed, 139 insertions, 24 deletions
diff --git a/ChangeLog b/ChangeLog
index 949858e3..22150b6d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+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.
+
2008-03-28 Benjamin Otte <otte@gnome.org>
* daemon/gvfsbackendftp.c: (ftp_connection_pop_job):
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 43e09e38..a191b4ce 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -398,7 +398,10 @@ do_sync_path_call (GFile *file,
{
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 @@ do_sync_path_call (GFile *file,
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 @@ do_sync_2_path_call (GFile *file1,
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 @@ do_sync_2_path_call (GFile *file1,
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 @@ g_daemon_file_set_attribute (GFile *file,
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_daemon_file_set_attribute (GFile *file,
_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;
diff --git a/client/gvfsdaemondbus.c b/client/gvfsdaemondbus.c
index 4a2cb45f..c062cbdc 100644
--- a/client/gvfsdaemondbus.c
+++ b/client/gvfsdaemondbus.c
@@ -65,6 +65,15 @@ static GHashTable *obj_path_map = NULL;
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 @@ _g_vfs_daemon_call_sync (DBusMessage *message,
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_daemon_call_sync (DBusMessage *message,
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 @@ _g_vfs_daemon_call_sync (DBusMessage *message,
&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 @@ free_local_connections (ThreadLocalConnections *local)
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 @@ _g_dbus_connection_get_sync (const char *dbus_id,
}
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 @@ _g_dbus_connection_get_sync (const char *dbus_id,
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,
diff --git a/client/gvfsdaemondbus.h b/client/gvfsdaemondbus.h
index 46874f7e..7a132cdc 100644
--- a/client/gvfsdaemondbus.h
+++ b/client/gvfsdaemondbus.h
@@ -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,