summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2013-09-26 12:03:36 +0200
committerAlexander Larsson <alexl@redhat.com>2013-09-26 12:38:30 +0200
commit65b8b938df26cfe04935b0195265971c7e278ab0 (patch)
tree03721b5995ef6b2b433bcfe32a82c471bb5e0a21
parentf252b6473c8c38d8fffbc03864db302f43f8e9ce (diff)
downloadgvfs-65b8b938df26cfe04935b0195265971c7e278ab0.tar.gz
GDaemonFileEnumerator: Only listen to messages one connection
There is no need to listen to messages on other connections than the one we sent the request on. In fact, doing so is bad as it can cause locking issues as per bug 708721. https://bugzilla.gnome.org/show_bug.cgi?id=708744
-rw-r--r--client/gdaemonfile.c11
-rw-r--r--client/gdaemonfileenumerator.c65
-rw-r--r--client/gdaemonfileenumerator.h2
3 files changed, 54 insertions, 24 deletions
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 25cb3cd0..a396211e 100644
--- a/client/gdaemonfile.c
+++ b/client/gdaemonfile.c
@@ -742,13 +742,13 @@ g_daemon_file_enumerate_children (GFile *file,
GVfsDBusMount *proxy;
gboolean res;
GError *local_error = NULL;
-
- enumerator = g_daemon_file_enumerator_new (file, attributes, TRUE);
proxy = create_proxy_for_file (file, NULL, &path, &connection, cancellable, error);
if (proxy == NULL)
- goto out;
-
+ return NULL;
+
+ enumerator = g_daemon_file_enumerator_new (file, proxy, attributes, TRUE);
+
obj_path = g_daemon_file_enumerator_get_object_path (enumerator);
uri = g_file_get_uri (file);
@@ -3366,6 +3366,8 @@ enumerate_children_async_get_proxy_cb (GVfsDBusMount *proxy,
char *obj_path;
char *uri;
+ data->enumerator = g_daemon_file_enumerator_new (data->file, proxy, data->attributes, FALSE);
+
obj_path = g_daemon_file_enumerator_get_object_path (data->enumerator);
uri = g_file_get_uri (data->file);
@@ -3404,7 +3406,6 @@ g_daemon_file_enumerate_children_async (GFile *file,
data->io_priority = io_priority;
if (cancellable)
data->cancellable = g_object_ref (cancellable);
- data->enumerator = g_daemon_file_enumerator_new (data->file, data->attributes, FALSE);
create_proxy_for_file_async (file,
cancellable,
diff --git a/client/gdaemonfileenumerator.c b/client/gdaemonfileenumerator.c
index 0c3c6974..63d6a914 100644
--- a/client/gdaemonfileenumerator.c
+++ b/client/gdaemonfileenumerator.c
@@ -48,6 +48,8 @@ struct _GDaemonFileEnumerator
gint id;
GDBusConnection *sync_connection; /* NULL if async, i.e. we're listening on main dbus connection */
+ GVfsDBusEnumerator *skeleton;
+
/* protected by infos lock */
GList *infos;
gboolean done;
@@ -100,17 +102,39 @@ free_info_list (GList *infos)
g_list_free_full (infos, g_object_unref);
}
+static guint
+add_timeout_for_context (GMainContext *context,
+ guint32 interval,
+ GSourceFunc function,
+ gpointer data)
+{
+ GSource *source;
+ guint id;
+
+ g_return_val_if_fail (function != NULL, 0);
+
+ source = g_timeout_source_new (interval);
+
+ g_source_set_callback (source, function, data, NULL);
+ id = g_source_attach (source, context);
+ g_source_unref (source);
+
+ return id;
+}
+
+
static void
g_daemon_file_enumerator_finalize (GObject *object)
{
GDaemonFileEnumerator *daemon;
- char *path;
daemon = G_DAEMON_FILE_ENUMERATOR (object);
- path = g_daemon_file_enumerator_get_object_path (daemon);
- _g_dbus_unregister_vfs_filter (path);
- g_free (path);
+ if (daemon->skeleton)
+ {
+ g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (daemon->skeleton));
+ g_object_unref (daemon->skeleton);
+ }
free_info_list (daemon->infos);
@@ -219,21 +243,20 @@ handle_got_info (GVfsDBusEnumerator *object,
return TRUE;
}
-static GDBusInterfaceSkeleton *
-register_vfs_filter_cb (GDBusConnection *connection,
- const char *obj_path,
- gpointer callback_data)
+static void
+create_skeleton (GDaemonFileEnumerator *daemon,
+ GDBusConnection *connection,
+ const char *obj_path)
{
- GError *error;
GVfsDBusEnumerator *skeleton;
- GDaemonFileEnumerator *daemon = G_DAEMON_FILE_ENUMERATOR (callback_data);
+ GError *error;
if (daemon->next_files_context)
g_main_context_push_thread_default (daemon->next_files_context);
skeleton = gvfs_dbus_enumerator_skeleton_new ();
- g_signal_connect (skeleton, "handle-done", G_CALLBACK (handle_done), callback_data);
- g_signal_connect (skeleton, "handle-got-info", G_CALLBACK (handle_got_info), callback_data);
+ g_signal_connect (skeleton, "handle-done", G_CALLBACK (handle_done), daemon);
+ g_signal_connect (skeleton, "handle-got-info", G_CALLBACK (handle_got_info), daemon);
error = NULL;
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (skeleton),
@@ -249,7 +272,7 @@ register_vfs_filter_cb (GDBusConnection *connection,
if (daemon->next_files_context)
g_main_context_pop_thread_default (daemon->next_files_context);
- return G_DBUS_INTERFACE_SKELETON (skeleton);
+ daemon->skeleton = skeleton;
}
static void
@@ -262,12 +285,14 @@ g_daemon_file_enumerator_init (GDaemonFileEnumerator *daemon)
GDaemonFileEnumerator *
g_daemon_file_enumerator_new (GFile *file,
+ GVfsDBusMount *mount_proxy,
const char *attributes,
gboolean sync)
{
GDaemonFileEnumerator *daemon;
char *treename;
char *path;
+ GThread *self = g_thread_self ();
daemon = g_object_new (G_TYPE_DAEMON_FILE_ENUMERATOR,
"container", file,
@@ -278,9 +303,10 @@ g_daemon_file_enumerator_new (GFile *file,
path = g_daemon_file_enumerator_get_object_path (daemon);
- _g_dbus_register_vfs_filter (path,
- register_vfs_filter_cb,
- G_OBJECT (daemon));
+ create_skeleton (daemon,
+ g_dbus_proxy_get_connection (G_DBUS_PROXY (mount_proxy)),
+ path);
+
g_free (path);
daemon->matcher = g_file_attribute_matcher_new (attributes);
@@ -482,10 +508,11 @@ g_daemon_file_enumerator_next_file (GFileEnumerator *enumerator,
daemon->next_files_mainloop = g_main_loop_new (daemon->next_files_context, FALSE);
g_mutex_unlock (&daemon->next_files_mutex);
-
+
g_main_context_push_thread_default (daemon->next_files_context);
- daemon->next_files_sync_timeout_tag = g_timeout_add (G_VFS_DBUS_TIMEOUT_MSECS,
- sync_timeout, daemon);
+ daemon->next_files_sync_timeout_tag = add_timeout_for_context (daemon->next_files_context,
+ G_VFS_DBUS_TIMEOUT_MSECS,
+ sync_timeout, daemon);
g_main_loop_run (daemon->next_files_mainloop);
g_main_context_pop_thread_default (daemon->next_files_context);
diff --git a/client/gdaemonfileenumerator.h b/client/gdaemonfileenumerator.h
index 8a94c3d8..f30737eb 100644
--- a/client/gdaemonfileenumerator.h
+++ b/client/gdaemonfileenumerator.h
@@ -24,6 +24,7 @@
#define __G_DAEMON_FILE_ENUMERATOR_H__
#include <gio/gio.h>
+#include <gvfsdbus.h>
G_BEGIN_DECLS
@@ -46,6 +47,7 @@ struct _GDaemonFileEnumeratorClass
GType g_daemon_file_enumerator_get_type (void) G_GNUC_CONST;
GDaemonFileEnumerator *g_daemon_file_enumerator_new (GFile *file,
+ GVfsDBusMount *proxy,
const char *attributes,
gboolean sync);
char * g_daemon_file_enumerator_get_object_path (GDaemonFileEnumerator *enumerator);