[tracker] TrackerMinerFS: turn process_file() into a signal.



commit d69801774a1de622504c1c60c4b47bdfca25004f
Author: Carlos Garnacho <carlos lanedo com>
Date:   Thu Oct 8 13:36:07 2009 +0200

    TrackerMinerFS: turn process_file() into a signal.
    
    This has been done to fit better with the rest of the API, also
    tracker_miner_fs_notify_file() has been added to replace the callback
    parameter, since implementations can do metadata extraction asynchronously,
    they'll be responsible of calling this function. Applications and files miners
    have been modified.

 src/libtracker-miner/tracker-marshal.list         |    1 +
 src/libtracker-miner/tracker-miner-fs.c           |  171 ++++++++++++++++-----
 src/libtracker-miner/tracker-miner-fs.h           |   27 +---
 src/tracker-miner-fs/tracker-miner-applications.c |   14 +--
 src/tracker-miner-fs/tracker-miner-files.c        |   23 +--
 5 files changed, 144 insertions(+), 92 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-marshal.list b/src/libtracker-miner/tracker-marshal.list
index d586289..f2f5e3f 100644
--- a/src/libtracker-miner/tracker-marshal.list
+++ b/src/libtracker-miner/tracker-marshal.list
@@ -4,6 +4,7 @@ VOID:POINTER,BOOLEAN,UINT,UINT,UINT,UINT
 VOID:DOUBLE,UINT,UINT,UINT,UINT
 VOID:STRING,STRING,DOUBLE
 VOID:STRING,DOUBLE
+BOOL:OBJECT,OBJECT,OBJECT
 BOOL:OBJECT,OBJECT
 BOOL:OBJECT,POINTER
 BOOL:OBJECT
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index a5a009e..ead0e7f 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -54,6 +54,7 @@ typedef struct {
 typedef struct {
 	GFile *file;
 	GCancellable *cancellable;
+	TrackerSparqlBuilder *builder;
 } ProcessData;
 
 struct TrackerMinerFSPrivate {
@@ -113,6 +114,7 @@ enum {
 	CHECK_DIRECTORY,
 	CHECK_DIRECTORY_CONTENTS,
 	MONITOR_DIRECTORY,
+	PROCESS_FILE,
 	FINISHED,
 	LAST_SIGNAL
 };
@@ -314,6 +316,38 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
 			      tracker_marshal_BOOLEAN__OBJECT,
 			      G_TYPE_BOOLEAN, 1, G_TYPE_FILE);
 	/**
+	 * TrackerMinerFS::process-file:
+	 * @miner_fs: the #TrackerMinerFS
+	 * @file: a #GFile
+	 * @builder: a #TrackerSparqlBuilder
+	 * @cancellable: a #GCancellable
+	 *
+	 * The ::process-file signal is emitted whenever a file should
+	 * be processed, and it's metadata extracted.
+	 *
+	 * @builder is the #TrackerSparqlBuilder where all sparql updates
+	 * to be performed for @file will be appended.
+	 *
+	 * This signal allows both synchronous and asynchronous extraction,
+	 * in the synchronous case @cancellable can be safely ignored. In
+	 * either case, on successful metadata extraction, implementations
+	 * must call tracker_miner_fs_notify_file() to indicate that
+	 * processing has finished on @file, so the miner can execute
+	 * the SPARQL updates and continue processing other files.
+	 *
+	 * Returns: %TRUE if the file is accepted for processing,
+	 *          %FALSE if the file should be ignored.
+	 **/
+	signals[PROCESS_FILE] =
+		g_signal_new ("process-file",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (TrackerMinerFSClass, process_file),
+			      NULL, NULL,
+			      tracker_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT,
+			      G_TYPE_BOOLEAN,
+			      3, G_TYPE_FILE, TRACKER_TYPE_SPARQL_BUILDER, G_TYPE_CANCELLABLE),
+	/**
 	 * TrackerMinerFS::finished:
 	 * @miner_fs: the #TrackerMinerFS
 	 * @elapsed: elapsed time since mining was started
@@ -351,6 +385,7 @@ tracker_miner_fs_init (TrackerMinerFS *object)
 	object->private = TRACKER_MINER_FS_GET_PRIVATE (object);
 
 	priv = object->private;
+	priv->pool_limit = 1;
 
 	/* For each module we create a TrackerCrawler and keep them in
 	 * a hash table to look up.
@@ -396,14 +431,16 @@ tracker_miner_fs_init (TrackerMinerFS *object)
 }
 
 static ProcessData *
-process_data_new (GFile        *file,
-		  GCancellable *cancellable)
+process_data_new (GFile                *file,
+		  GCancellable         *cancellable,
+		  TrackerSparqlBuilder *builder)
 {
 	ProcessData *data;
 
 	data = g_slice_new (ProcessData);
 	data->file = g_object_ref (file);
 	data->cancellable = g_object_ref (cancellable);
+	data->builder = g_object_ref (builder);
 
 	return data;
 }
@@ -413,6 +450,7 @@ process_data_free (ProcessData *data)
 {
 	g_object_unref (data->file);
 	g_object_unref (data->cancellable);
+	g_object_unref (data->builder);
 	g_slice_free (ProcessData, data);
 }
 
@@ -707,16 +745,13 @@ item_moved_data_free (ItemMovedData *data)
 }
 
 static void
-item_add_or_update_cb (TrackerMinerFS       *fs,
-		       GFile                *file,
-		       TrackerSparqlBuilder *sparql,
-		       const GError         *error,
-		       gpointer              user_data)
+item_add_or_update_cb (TrackerMinerFS *fs,
+		       ProcessData    *data,
+		       const GError   *error)
 {
-	ProcessData *data;
 	gchar *uri;
 
-	uri = g_file_get_uri (file);
+	uri = g_file_get_uri (data->file);
 
 	if (error) {
 		g_message ("Could not process '%s': %s", uri, error->message);
@@ -726,7 +761,7 @@ item_add_or_update_cb (TrackerMinerFS       *fs,
 		g_debug ("Adding item '%s'", uri);
 
 		full_sparql = g_strdup_printf ("DROP GRAPH <%s> %s",
-					       uri, tracker_sparql_builder_get_result (sparql));
+					       uri, tracker_sparql_builder_get_result (data->builder));
 
 		tracker_miner_execute_batch_update (TRACKER_MINER (fs), full_sparql, NULL);
 		g_free (full_sparql);
@@ -739,25 +774,13 @@ item_add_or_update_cb (TrackerMinerFS       *fs,
 		}
 	}
 
-	data = process_data_find (fs, file);
-
-	if (data) {
-		process_data_free (data);
-		fs->private->processing_pool =
-			g_list_remove (fs->private->processing_pool, data);
-	}
-
-	/* Can be NULL on error */
-	if (sparql) {
-		g_object_unref (sparql);
-	}
+	fs->private->processing_pool =
+		g_list_remove (fs->private->processing_pool, data);
+	process_data_free (data);
 
 	g_free (uri);
 
-	if (g_list_length (fs->private->processing_pool) < fs->private->pool_limit) {
-		/* There is room in the pool for more files */
-		item_queue_handlers_set_up (fs);
-	}
+	item_queue_handlers_set_up (fs);
 }
 
 static gboolean
@@ -767,38 +790,57 @@ item_add_or_update (TrackerMinerFS *fs,
 	TrackerMinerFSPrivate *priv;
 	TrackerSparqlBuilder *sparql;
 	GCancellable *cancellable;
-	gboolean processing;
+	gboolean processing, retval;
+	ProcessData *data;
 
 	priv = fs->private;
+	retval = TRUE;
+
 	cancellable = g_cancellable_new ();
 	sparql = tracker_sparql_builder_new_update ();
+	g_object_ref (file);
+
+	data = process_data_new (file, cancellable, sparql);
+	priv->processing_pool = g_list_prepend (priv->processing_pool, data);
 
-	processing = TRACKER_MINER_FS_GET_CLASS (fs)->process_file (fs, file, sparql,
-								    cancellable,
-								    item_add_or_update_cb,
-								    NULL);
+	g_signal_emit (fs, signals[PROCESS_FILE], 0,
+		       file, sparql, cancellable,
+		       &processing);
 
 	if (!processing) {
-		g_object_unref (sparql);
-		g_object_unref (cancellable);
+		/* Re-fetch data, since it might have been
+		 * removed in broken implementations
+		 */
+		data = process_data_find (fs, file);
 
-		return TRUE;
+		if (!data) {
+			gchar *uri;
+
+			uri = g_file_get_uri (file);
+			g_critical ("%s has returned FALSE in ::process-file for '%s', "
+				    "but it seems that this file has been processed through "
+				    "tracker_miner_fs_notify_file(), this is an "
+				    "implementation error", G_OBJECT_TYPE_NAME (fs), uri);
+			g_free (uri);
+		} else {
+			priv->processing_pool = g_list_remove (priv->processing_pool, data);
+			process_data_free (data);
+		}
 	} else {
-		ProcessData *data;
 		guint length;
 
-		data = process_data_new (file, cancellable);
-		priv->processing_pool = g_list_prepend (priv->processing_pool, data);
 		length = g_list_length (priv->processing_pool);
 
-		g_object_unref (cancellable);
-
 		if (length >= priv->pool_limit) {
-			return FALSE;
-		} else {
-			return TRUE;
+			retval = FALSE;
 		}
 	}
+
+	g_object_unref (file);
+	g_object_unref (cancellable);
+	g_object_unref (sparql);
+
+	return retval;
 }
 
 static gboolean
@@ -1156,6 +1198,11 @@ item_queue_handlers_set_up (TrackerMinerFS *fs)
 		return;
 	}
 
+	if (g_list_length (fs->private->processing_pool) >= fs->private->pool_limit) {
+		/* There is no room in the pool for more files */
+		return;
+	}
+
 	g_object_get (fs, "status", &status, NULL);
 
 	if (g_strcmp0 (status, _("Processing files")) != 0) {
@@ -1852,3 +1899,43 @@ tracker_miner_fs_get_throttle (TrackerMinerFS *fs)
 
 	return fs->private->throttle;
 }
+
+/**
+ * tracker_miner_fs_notify_file:
+ * @fs: a #TrackerMinerFS
+ * @file: a #GFile
+ * @error: a #GError with the error that happened during processing, or %NULL.
+ *
+ * Notifies @fs that all processing on @file has been finished, if any error
+ * happened during file data processing, it should be passed in @error, else
+ * that parameter will contain %NULL to reflect success.
+ **/
+void
+tracker_miner_fs_notify_file (TrackerMinerFS *fs,
+			      GFile          *file,
+			      const GError   *error)
+{
+	ProcessData *data;
+
+	g_return_if_fail (TRACKER_IS_MINER_FS (fs));
+	g_return_if_fail (G_IS_FILE (file));
+
+	data = process_data_find (fs, file);
+
+	if (!data) {
+		gchar *uri;
+
+		uri = g_file_get_uri (file);
+		g_critical ("%s has notified that file '%s' has been processed, "
+			    "but that file was not in the processing queue. "
+			    "This is an implementation error, please ensure that "
+			    "tracker_miner_fs_notify_file() is called on the right "
+			    "file and that the ::process-file signal didn't return "
+			    "FALSE for it", G_OBJECT_TYPE_NAME (fs), uri);
+		g_free (uri);
+
+		return;
+	}
+
+	item_add_or_update_cb (fs, data, error);
+}
diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h
index 6f266f9..ccc0d68 100644
--- a/src/libtracker-miner/tracker-miner-fs.h
+++ b/src/libtracker-miner/tracker-miner-fs.h
@@ -40,25 +40,6 @@ G_BEGIN_DECLS
 typedef struct TrackerMinerFS        TrackerMinerFS;
 typedef struct TrackerMinerFSPrivate TrackerMinerFSPrivate;
 
-/**
- * TrackerMinerFSDoneCb:
- * @fs: The #TrackerMinerFS
- * @file: The #GFile corresponding to the asynchronous call
- * @builder: a #TrackerSparqlBuilder to collect data
- * @error: #GError with the extraction error, or %NULL if none
- * @user_data: passed user data to the asynchronous call
- *
- * This callback is passed for each inspected #GFile in the
- * TrackerMinerFS::process_file() vmethod, it's the implementation
- * responsibility to call it as soon as all metadata extraction has
- * been performed on @file.
- **/
-typedef void (* TrackerMinerFSDoneCb) (TrackerMinerFS       *fs,
-				       GFile                *file,
-				       TrackerSparqlBuilder *builder,
-				       const GError         *error,
-				       gpointer              user_data);
-
 struct TrackerMinerFS {
 	TrackerMiner parent;
 	TrackerMinerFSPrivate *private;
@@ -91,9 +72,7 @@ typedef struct {
 	gboolean (* process_file)          (TrackerMinerFS       *fs,
 					    GFile                *file,
 					    TrackerSparqlBuilder *builder,
-					    GCancellable         *cancellable,
-					    TrackerMinerFSDoneCb  done_cb,
-					    gpointer              done_cb_data);
+					    GCancellable         *cancellable);
 	gboolean (* monitor_directory)     (TrackerMinerFS       *fs,
 					    GFile                *file);
 	void     (* finished)              (TrackerMinerFS       *fs);
@@ -111,6 +90,10 @@ void     tracker_miner_fs_set_throttle     (TrackerMinerFS *fs,
 					    gdouble         throttle);
 gdouble  tracker_miner_fs_get_throttle     (TrackerMinerFS *fs);
 
+void     tracker_miner_fs_notify_file      (TrackerMinerFS *fs,
+					    GFile          *file,
+					    const GError   *error);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKERMINER_MINER_FS_H__ */
diff --git a/src/tracker-miner-fs/tracker-miner-applications.c b/src/tracker-miner-fs/tracker-miner-applications.c
index da77fa7..7dc8e12 100644
--- a/src/tracker-miner-fs/tracker-miner-applications.c
+++ b/src/tracker-miner-fs/tracker-miner-applications.c
@@ -47,9 +47,7 @@ static gboolean miner_applications_check_directory   (TrackerMinerFS       *fs,
 static gboolean miner_applications_process_file      (TrackerMinerFS       *fs,
 						      GFile                *file,
 						      TrackerSparqlBuilder *sparql,
-						      GCancellable         *cancellable,
-						      TrackerMinerFSDoneCb  done_cb,
-						      gpointer              done_cb_data);
+						      GCancellable         *cancellable);
 static gboolean miner_applications_monitor_directory (TrackerMinerFS       *fs,
 						      GFile                *file);
 
@@ -61,8 +59,6 @@ struct ProcessApplicationData {
 	TrackerMinerFS *miner;
 	GFile *file;
 	TrackerSparqlBuilder *sparql;
-	TrackerMinerFSDoneCb callback;
-	gpointer callback_data;
 	GCancellable *cancellable;
 	GKeyFile *key_file;
 	gchar *type;
@@ -417,7 +413,7 @@ miner_applications_process_file_cb (gpointer user_data)
 	tracker_sparql_builder_insert_close (sparql);
 
 	/* Notify about success */
-	data->callback (data->miner, data->file, sparql, NULL, data->callback_data);
+	tracker_miner_fs_notify_file (data->miner, data->file, NULL);
 
 	g_strfreev (cats);
 
@@ -444,9 +440,7 @@ static gboolean
 miner_applications_process_file (TrackerMinerFS       *fs,
 				 GFile                *file,
 				 TrackerSparqlBuilder *sparql,
-				 GCancellable         *cancellable,
-				 TrackerMinerFSDoneCb  done_cb,
-				 gpointer              done_cb_data)
+				 GCancellable         *cancellable)
 {
 	ProcessApplicationData *data;
 	GKeyFile *key_file;
@@ -462,8 +456,6 @@ miner_applications_process_file (TrackerMinerFS       *fs,
 	data->miner = g_object_ref (fs);
 	data->sparql = g_object_ref (sparql);
 	data->file = g_object_ref (file);
-	data->callback = done_cb;
-	data->callback_data = done_cb_data;
 	data->cancellable = g_object_ref (cancellable);
 	data->key_file = key_file;
 	data->type = type;
diff --git a/src/tracker-miner-fs/tracker-miner-files.c b/src/tracker-miner-fs/tracker-miner-files.c
index 4861a4c..0a5913d 100644
--- a/src/tracker-miner-fs/tracker-miner-files.c
+++ b/src/tracker-miner-fs/tracker-miner-files.c
@@ -49,8 +49,6 @@ typedef struct ProcessFileData ProcessFileData;
 struct ProcessFileData {
 	TrackerMinerFiles *miner;
 	TrackerSparqlBuilder *sparql;
-	TrackerMinerFSDoneCb callback;
-	gpointer callback_data;
 	GCancellable *cancellable;
 	GFile *file;
 	DBusGProxyCall *call;
@@ -141,9 +139,7 @@ static gboolean miner_files_check_directory_contents (TrackerMinerFS       *fs,
 static gboolean miner_files_process_file      (TrackerMinerFS       *fs,
 					       GFile                *file,
 					       TrackerSparqlBuilder *sparql,
-					       GCancellable         *cancellable,
-					       TrackerMinerFSDoneCb  done_cb,
-					       gpointer              done_cb_data);
+					       GCancellable         *cancellable);
 static gboolean miner_files_monitor_directory (TrackerMinerFS       *fs,
 					       GFile                *file);
 
@@ -760,7 +756,6 @@ on_low_battery_cb (GObject    *object,
 		if (mf->private->low_battery_pause_cookie == 0) {
 			mf->private->low_battery_pause_cookie = 
 				tracker_miner_pause (TRACKER_MINER (mf),
-						     g_get_application_name (),
 						     _("Low battery"),
 						     NULL);
 		}
@@ -848,7 +843,6 @@ disk_space_check_cb (gpointer user_data)
 		if (mf->private->disk_space_pause_cookie == 0) {
 			mf->private->disk_space_pause_cookie = 
 				tracker_miner_pause (TRACKER_MINER (mf),
-						     g_get_application_name (),
 						     _("Low disk space"),
 						     NULL);
 		}
@@ -1208,7 +1202,7 @@ extractor_get_embedded_metadata_cb (DBusGProxy *proxy,
 
 	if (error) {
 		/* Something bad happened, notify about the error */
-		data->callback (TRACKER_MINER_FS (data->miner), data->file, data->sparql, error, data->callback_data);
+		tracker_miner_fs_notify_file (TRACKER_MINER_FS (data->miner), data->file, error);
 		process_file_data_free (data);
 		g_error_free (error);
 		return;
@@ -1220,9 +1214,8 @@ extractor_get_embedded_metadata_cb (DBusGProxy *proxy,
 		g_free (sparql);
 	}
 
-
 	/* Notify about the success */
-	data->callback (TRACKER_MINER_FS (data->miner), data->file, data->sparql, NULL, data->callback_data);
+	tracker_miner_fs_notify_file (TRACKER_MINER_FS (data->miner), data->file, NULL);
 	process_file_data_free (data);
 }
 
@@ -1237,7 +1230,7 @@ extractor_get_embedded_metadata_cancel (GCancellable    *cancellable,
 				  data->call);
 
 	error = g_error_new_literal (miner_files_error_quark, 0, "Embedded metadata extraction was cancelled");
-	data->callback (TRACKER_MINER_FS (data->miner), data->file, data->sparql, error, data->callback_data);
+	tracker_miner_fs_notify_file (TRACKER_MINER_FS (data->miner), data->file, error);
 
 	process_file_data_free (data);
 	g_error_free (error);
@@ -1278,7 +1271,7 @@ process_file_cb (GObject      *object,
 
 	if (error) {
 		/* Something bad happened, notify about the error */
-		data->callback (TRACKER_MINER_FS (data->miner), file, sparql, error, data->callback_data);
+		tracker_miner_fs_notify_file (TRACKER_MINER_FS (data->miner), file, error);
 		process_file_data_free (data);
 		return;
 	}
@@ -1347,16 +1340,12 @@ static gboolean
 miner_files_process_file (TrackerMinerFS       *fs,
 			  GFile                *file,
 			  TrackerSparqlBuilder *sparql,
-			  GCancellable         *cancellable,
-			  TrackerMinerFSDoneCb  done_cb,
-			  gpointer              done_cb_data)
+			  GCancellable         *cancellable)
 {
 	ProcessFileData *data;
 	const gchar *attrs;
 
 	data = g_slice_new0 (ProcessFileData);
-	data->callback = done_cb;
-	data->callback_data = done_cb_data;
 	data->miner = g_object_ref (fs);
 	data->cancellable = g_object_ref (cancellable);
 	data->sparql = g_object_ref (sparql);



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