[gvfs] GDaemonFileEnumerator: Only listen to messages one connection



commit 65b8b938df26cfe04935b0195265971c7e278ab0
Author: Alexander Larsson <alexl redhat com>
Date:   Thu Sep 26 12:03:36 2013 +0200

    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

 client/gdaemonfile.c           |   11 ++++---
 client/gdaemonfileenumerator.c |   65 ++++++++++++++++++++++++++++-----------
 client/gdaemonfileenumerator.h |    2 +
 3 files changed, 54 insertions(+), 24 deletions(-)
---
diff --git a/client/gdaemonfile.c b/client/gdaemonfile.c
index 25cb3cd..a396211 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 0c3c697..63d6a91 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 8a94c3d..f30737e 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);


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