Blob Blame History Raw
From 409606679702536cfb207282c3d034eace83f2a4 Mon Sep 17 00:00:00 2001
From: Debarshi Ray <debarshir@gnome.org>
Date: Wed, 1 Oct 2014 19:31:01 +0200
Subject: [PATCH 1/2] libtracker-miner: Ensure that the async function uses
 owned data

... and simplify parent directory tracking.

The GFileEnumerator keeps a reference to the directory that is being
traversed, so we don't need to keep track of it ourselves.

https://bugzilla.gnome.org/show_bug.cgi?id=737768
---
 src/libtracker-miner/tracker-crawler.c | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/src/libtracker-miner/tracker-crawler.c b/src/libtracker-miner/tracker-crawler.c
index c034204..2c6e0f0 100644
--- a/src/libtracker-miner/tracker-crawler.c
+++ b/src/libtracker-miner/tracker-crawler.c
@@ -105,7 +105,6 @@ typedef struct {
 	TrackerCrawler *crawler;
 	DirectoryRootInfo  *root_info;
 	DirectoryProcessingData *dir_info;
-	GFile *dir_file;
 	GCancellable *cancellable;
 } EnumeratorData;
 
@@ -596,9 +595,6 @@ enumerator_data_new (TrackerCrawler          *crawler,
 	ed->crawler = g_object_ref (crawler);
 	ed->root_info = root_info;
 	ed->dir_info = dir_info;
-	/* Make sure there's always a ref of the GFile while we're
-	 * iterating it */
-	ed->dir_file = g_object_ref (G_FILE (dir_info->node->data));
 	ed->cancellable = g_cancellable_new ();
 
 	crawler->priv->cancellables = g_list_prepend (crawler->priv->cancellables,
@@ -607,7 +603,7 @@ enumerator_data_new (TrackerCrawler          *crawler,
 }
 
 static void
-enumerator_data_process (EnumeratorData *ed)
+enumerator_data_process (GFile *parent, EnumeratorData *ed)
 {
 	TrackerCrawler *crawler;
 	GSList *l;
@@ -623,7 +619,7 @@ enumerator_data_process (EnumeratorData *ed)
 		children = g_list_prepend (children, child_data->child);
 	}
 
-	g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, ed->dir_info->node->data, children, &use);
+	g_signal_emit (crawler, signals[CHECK_DIRECTORY_CONTENTS], 0, parent, children, &use);
 	g_list_free (children);
 
 	if (!use) {
@@ -640,7 +636,6 @@ enumerator_data_free (EnumeratorData *ed)
 		g_list_remove (ed->crawler->priv->cancellables,
 			       ed->cancellable);
 
-	g_object_unref (ed->dir_file);
 	g_object_unref (ed->crawler);
 	g_object_unref (ed->cancellable);
 	g_slice_free (EnumeratorData, ed);
@@ -690,6 +685,7 @@ file_enumerate_next_cb (GObject      *object,
 	ed = user_data;
 	crawler = ed->crawler;
 	cancelled = g_cancellable_is_cancelled (ed->cancellable);
+	parent = g_file_enumerator_get_container (enumerator);
 
 	files = g_file_enumerator_next_files_finish (enumerator,
 	                                             result,
@@ -710,7 +706,7 @@ file_enumerate_next_cb (GObject      *object,
 		}
 
 		if (!cancelled) {
-			enumerator_data_process (ed);
+			enumerator_data_process (parent, ed);
 		}
 
 		enumerator_data_free (ed);
@@ -724,8 +720,6 @@ file_enumerate_next_cb (GObject      *object,
 		return;
 	}
 
-	parent = ed->dir_info->node->data;
-
 	for (l = files; l; l = l->next) {
 		const gchar *child_name;
 		gboolean is_dir;
@@ -814,6 +808,7 @@ file_enumerate_children (TrackerCrawler          *crawler,
 			 DirectoryProcessingData *dir_data)
 {
 	EnumeratorData *ed;
+	GFile *dir_file;
 	gchar *attrs;
 
 	ed = enumerator_data_new (crawler, info, dir_data);
@@ -826,7 +821,8 @@ file_enumerate_children (TrackerCrawler          *crawler,
 		attrs = g_strdup (FILE_ATTRIBUTES);
 	}
 
-	g_file_enumerate_children_async (ed->dir_file,
+	dir_file = G_FILE (dir_data->node->data);
+	g_file_enumerate_children_async (dir_file,
 	                                 attrs,
 	                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
 	                                 G_PRIORITY_LOW,
-- 
2.1.0


From 0018667159e02a4b9e51ad2c9bbd76d666fbfe56 Mon Sep 17 00:00:00 2001
From: Debarshi Ray <debarshir@gnome.org>
Date: Wed, 1 Oct 2014 19:44:42 +0200
Subject: [PATCH 2/2] libtracker-miner: Keep the crawler alive across async
 calls

The EnumeratorData held a reference to TrackerCrawler while
enumerating. Just before closing the enumerator we destroy the
EnumeratorData and drop the reference. This can lead to TrackerCrawler
getting destroyed.

To prevent this, grab a new reference before dropping the older one
and keep it till the asynchronous call is alive.

https://bugzilla.gnome.org/show_bug.cgi?id=737769
---
 src/libtracker-miner/tracker-crawler.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/libtracker-miner/tracker-crawler.c b/src/libtracker-miner/tracker-crawler.c
index 2c6e0f0..80befde 100644
--- a/src/libtracker-miner/tracker-crawler.c
+++ b/src/libtracker-miner/tracker-crawler.c
@@ -664,6 +664,7 @@ file_enumerator_close_cb (GObject      *enumerator,
 	 * continue with queued files/directories.
 	 */
 	process_func_start (crawler);
+	g_object_unref (crawler);
 }
 
 static void
@@ -709,12 +710,12 @@ file_enumerate_next_cb (GObject      *object,
 			enumerator_data_process (parent, ed);
 		}
 
-		enumerator_data_free (ed);
 		g_file_enumerator_close_async (enumerator,
 		                               G_PRIORITY_DEFAULT,
 		                               NULL,
 		                               file_enumerator_close_cb,
-		                               crawler);
+		                               g_object_ref (crawler));
+		enumerator_data_free (ed);
 		g_object_unref (enumerator);
 
 		return;
-- 
2.1.0