[tracker/libtracker-miner] TrackerMinerFS: make process_file() vmethod asynchronous and possibly cancellable.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [tracker/libtracker-miner] TrackerMinerFS: make process_file() vmethod asynchronous and possibly cancellable.
- Date: Fri, 28 Aug 2009 11:48:01 +0000 (UTC)
commit 98966db3c63a617c331d00ed04bf78de169ed949
Author: Carlos Garnacho <carlos lanedo com>
Date: Fri Aug 28 12:08:24 2009 +0200
TrackerMinerFS: make process_file() vmethod asynchronous and possibly cancellable.
TrackerMinerFiles and TrackerMinerApplications have changed to implement it in an
asynchronous fashion. The cancellable will be used in the future to cancel ongoing
operations on removable devices.
src/libtracker-miner/tracker-miner-fs.c | 133 ++++++++++++++-------
src/libtracker-miner/tracker-miner-fs.h | 11 ++-
src/tracker-miner-fs/tracker-miner-applications.c | 123 ++++++++++++++++----
src/tracker-miner-fs/tracker-miner-files.c | 109 +++++++++++++----
4 files changed, 285 insertions(+), 91 deletions(-)
---
diff --git a/src/libtracker-miner/tracker-miner-fs.c b/src/libtracker-miner/tracker-miner-fs.c
index 686c0c7..4db8640 100644
--- a/src/libtracker-miner/tracker-miner-fs.c
+++ b/src/libtracker-miner/tracker-miner-fs.c
@@ -60,6 +60,8 @@ struct TrackerMinerFSPrivate {
guint crawl_directories_id;
guint item_queues_handler_id;
+ GCancellable *cancellable;
+
/* Status */
guint been_started : 1;
guint been_crawled : 1;
@@ -88,7 +90,6 @@ enum {
enum {
CHECK_FILE,
CHECK_DIRECTORY,
- PROCESS_FILE,
MONITOR_DIRECTORY,
FINISHED,
LAST_SIGNAL
@@ -140,6 +141,9 @@ static void crawler_finished_cb (TrackerCrawler *crawler,
static void crawl_directories_start (TrackerMinerFS *fs);
static void crawl_directories_stop (TrackerMinerFS *fs);
+static void item_queue_handlers_set_up (TrackerMinerFS *fs);
+
+
static guint signals[LAST_SIGNAL] = { 0, };
G_DEFINE_ABSTRACT_TYPE (TrackerMinerFS, tracker_miner_fs, TRACKER_TYPE_MINER)
@@ -184,15 +188,6 @@ tracker_miner_fs_class_init (TrackerMinerFSClass *klass)
NULL,
tracker_marshal_BOOLEAN__OBJECT,
G_TYPE_BOOLEAN, 1, G_TYPE_FILE);
- signals[PROCESS_FILE] =
- g_signal_new ("process-file",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (TrackerMinerFSClass, process_file),
- tracker_accumulator_check_file,
- NULL,
- tracker_marshal_BOOLEAN__OBJECT_OBJECT,
- G_TYPE_BOOLEAN, 2, G_TYPE_FILE, TRACKER_TYPE_SPARQL_BUILDER);
signals[MONITOR_DIRECTORY] =
g_signal_new ("monitor-directory",
G_OBJECT_CLASS_TYPE (object_class),
@@ -270,6 +265,7 @@ tracker_miner_fs_init (TrackerMinerFS *object)
object);
priv->quark_ignore_file = g_quark_from_static_string ("tracker-ignore-file");
+ priv->cancellable = g_cancellable_new ();
}
static void
@@ -292,6 +288,7 @@ fs_finalize (GObject *object)
g_object_unref (priv->crawler);
g_object_unref (priv->monitor);
+ g_object_unref (priv->cancellable);
if (priv->directories) {
g_list_foreach (priv->directories, (GFunc) directory_data_free, NULL);
@@ -449,33 +446,71 @@ item_moved_data_free (ItemMovedData *data)
}
static void
-item_add_or_update (TrackerMinerFS *miner,
- GFile *file)
+item_add_or_update_cb (TrackerMinerFS *fs,
+ GFile *file,
+ TrackerSparqlBuilder *sparql,
+ const GError *error,
+ gpointer user_data)
{
- TrackerSparqlBuilder *sparql;
- gchar *full_sparql, *uri;
- gboolean processed;
+ gchar *uri;
- sparql = tracker_sparql_builder_new_update ();
- g_signal_emit (miner, signals[PROCESS_FILE], 0, file, sparql, &processed);
+ uri = g_file_get_uri (file);
- if (!processed) {
- g_object_unref (sparql);
- return;
- }
+ if (error) {
+ g_warning ("Could not process '%s': %s", uri, error->message);
- uri = g_file_get_uri (file);
+ } else {
+ gchar *full_sparql;
- g_debug ("Adding item '%s'", uri);
+ g_debug ("Adding item '%s'", uri);
- tracker_sparql_builder_insert_close (sparql);
+ tracker_sparql_builder_insert_close (sparql);
- full_sparql = g_strdup_printf ("DROP GRAPH <%s> %s",
- uri, tracker_sparql_builder_get_result (sparql));
+ full_sparql = g_strdup_printf ("DROP GRAPH <%s> %s",
+ uri, tracker_sparql_builder_get_result (sparql));
+
+ tracker_miner_execute_sparql (TRACKER_MINER (fs), full_sparql, NULL);
+ g_free (full_sparql);
+ }
+
+ if (fs->private->cancellable) {
+ g_object_unref (fs->private->cancellable);
+ fs->private->cancellable = NULL;
+ }
- tracker_miner_execute_sparql (TRACKER_MINER (miner), full_sparql, NULL);
- g_free (full_sparql);
g_object_unref (sparql);
+ g_free (uri);
+
+ /* Processing is now done, continue with other files */
+ item_queue_handlers_set_up (fs);
+}
+
+static gboolean
+item_add_or_update (TrackerMinerFS *fs,
+ GFile *file)
+{
+ TrackerSparqlBuilder *sparql;
+ gboolean processing;
+
+ if (fs->private->cancellable) {
+ g_warning ("Cancellable for older operation still around, destroying");
+ g_object_unref (fs->private->cancellable);
+ }
+
+ fs->private->cancellable = g_cancellable_new ();
+ sparql = tracker_sparql_builder_new_update ();
+
+ processing = TRACKER_MINER_FS_GET_CLASS (fs)->process_file (fs, file, sparql,
+ fs->private->cancellable,
+ item_add_or_update_cb,
+ NULL);
+
+ if (!processing) {
+ g_object_unref (sparql);
+ return TRUE;
+ }
+
+ return FALSE;
}
static gboolean
@@ -576,7 +611,7 @@ update_file_uri_recursively (TrackerMinerFS *fs,
}
}
-static void
+static gboolean
item_move (TrackerMinerFS *fs,
GFile *file,
GFile *source_file)
@@ -590,14 +625,16 @@ item_move (TrackerMinerFS *fs,
/* Get 'source' ID */
if (!item_query_exists (fs, source_file)) {
+ gboolean retval;
+
g_message ("Source file '%s' not found in store to move, indexing '%s' from scratch", source_uri, uri);
- item_add_or_update (fs, file);
+ retval = item_add_or_update (fs, file);
g_free (source_uri);
g_free (uri);
- return;
+ return retval;
}
file_info = g_file_query_info (file,
@@ -612,7 +649,7 @@ item_move (TrackerMinerFS *fs,
g_free (source_uri);
g_free (uri);
- return;
+ return TRUE;
}
sparql = g_string_new ("");
@@ -639,6 +676,8 @@ item_move (TrackerMinerFS *fs,
g_free (source_uri);
g_object_unref (file_info);
g_string_free (sparql, TRUE);
+
+ return TRUE;
}
static gint
@@ -721,7 +760,8 @@ item_queue_handlers_cb (gpointer user_data)
GFile *file, *source_file;
gint queue;
GTimeVal time_now;
- static GTimeVal time_last = { 0, 0 };
+ static GTimeVal time_last = { 0 };
+ gboolean keep_processing = TRUE;
fs = user_data;
queue = item_queue_get_next_file (fs, &file, &source_file);
@@ -735,37 +775,42 @@ item_queue_handlers_cb (gpointer user_data)
}
/* Handle queues */
- if (queue == QUEUE_NONE) {
+ switch (queue) {
+ case QUEUE_NONE:
/* Print stats and signal finished */
process_stop (fs);
/* No more files left to process */
- fs->private->item_queues_handler_id = 0;
- return FALSE;
- }
-
- switch (queue) {
+ keep_processing = FALSE;
+ break;
case QUEUE_MOVED:
- item_move (fs, file, source_file);
+ keep_processing = item_move (fs, file, source_file);
break;
case QUEUE_DELETED:
item_remove (fs, file);
break;
case QUEUE_CREATED:
case QUEUE_UPDATED:
- item_add_or_update (fs, file);
+ keep_processing = item_add_or_update (fs, file);
break;
default:
g_assert_not_reached ();
}
- g_object_unref (file);
+ if (file) {
+ g_object_unref (file);
+ }
if (source_file) {
g_object_unref (source_file);
}
- return TRUE;
+ if (!keep_processing) {
+ fs->private->item_queues_handler_id = 0;
+ return FALSE;
+ } else {
+ return TRUE;
+ }
}
static void
@@ -795,7 +840,7 @@ should_change_index_for_file (TrackerMinerFS *fs,
guint64 time;
time_t mtime;
struct tm t;
- gchar *query, *uri;;
+ gchar *query, *uri;
file_info = g_file_query_info (file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
diff --git a/src/libtracker-miner/tracker-miner-fs.h b/src/libtracker-miner/tracker-miner-fs.h
index ce3d61a..d8da89d 100644
--- a/src/libtracker-miner/tracker-miner-fs.h
+++ b/src/libtracker-miner/tracker-miner-fs.h
@@ -41,6 +41,12 @@ typedef struct TrackerMinerFS TrackerMinerFS;
typedef struct TrackerMinerFSClass TrackerMinerFSClass;
typedef struct TrackerMinerFSPrivate TrackerMinerFSPrivate;
+typedef void (* TrackerMinerFSDoneCb) (TrackerMinerFS *fs,
+ GFile *file,
+ TrackerSparqlBuilder *builder,
+ const GError *error,
+ gpointer user_data);
+
struct TrackerMinerFS {
TrackerMiner parent;
TrackerMinerFSPrivate *private;
@@ -55,7 +61,10 @@ struct TrackerMinerFSClass {
GFile *file);
gboolean (* process_file) (TrackerMinerFS *fs,
GFile *file,
- TrackerSparqlBuilder *builder);
+ TrackerSparqlBuilder *builder,
+ GCancellable *cancellable,
+ TrackerMinerFSDoneCb done_cb,
+ gpointer done_cb_data);
gboolean (* monitor_directory) (TrackerMinerFS *fs,
GFile *file);
void (* finished) (TrackerMinerFS *fs);
diff --git a/src/tracker-miner-fs/tracker-miner-applications.c b/src/tracker-miner-fs/tracker-miner-applications.c
index 1618c73..9cddf8b 100644
--- a/src/tracker-miner-fs/tracker-miner-applications.c
+++ b/src/tracker-miner-fs/tracker-miner-applications.c
@@ -46,10 +46,27 @@ static gboolean miner_applications_check_directory (TrackerMinerFS *fs,
GFile *file);
static gboolean miner_applications_process_file (TrackerMinerFS *fs,
GFile *file,
- TrackerSparqlBuilder *sparql);
+ TrackerSparqlBuilder *sparql,
+ GCancellable *cancellable,
+ TrackerMinerFSDoneCb done_cb,
+ gpointer done_cb_data);
static gboolean miner_applications_monitor_directory (TrackerMinerFS *fs,
GFile *file);
+static GQuark miner_applications_error_quark = 0;
+
+typedef struct ProcessApplicationData ProcessApplicationData;
+
+struct ProcessApplicationData {
+ TrackerMinerFS *miner;
+ GFile *file;
+ TrackerSparqlBuilder *sparql;
+ TrackerMinerFSDoneCb callback;
+ gpointer callback_data;
+ GCancellable *cancellable;
+ GKeyFile *desktop_file;
+};
+
G_DEFINE_TYPE (TrackerMinerApplications, tracker_miner_applications, TRACKER_TYPE_MINER_FS)
static void
@@ -65,6 +82,8 @@ tracker_miner_applications_class_init (TrackerMinerApplicationsClass *klass)
miner_fs_class->check_directory = miner_applications_check_directory;
miner_fs_class->monitor_directory = miner_applications_monitor_directory;
miner_fs_class->process_file = miner_applications_process_file;
+
+ miner_applications_error_quark = g_quark_from_static_string ("TrackerMinerApplications");
}
static void
@@ -156,40 +175,63 @@ miner_applications_monitor_directory (TrackerMinerFS *fs,
return TRUE;
}
-static gboolean
-miner_applications_process_file (TrackerMinerFS *fs,
- GFile *file,
- TrackerSparqlBuilder *sparql)
+static GKeyFile *
+get_desktop_key_file (GFile *file,
+ gchar **type,
+ GError **error)
{
GKeyFile *key_file;
- gchar *path, *type, *filename, *name = NULL, *uri = NULL;
- GFileInfo *file_info;
- GStrv cats = NULL;
- gsize cats_len;
+ gchar *path;
path = g_file_get_path (file);
key_file = g_key_file_new ();
if (!g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL)) {
- g_debug ("Couldn't load desktop file:'%s'", path);
+ *error = g_error_new (miner_applications_error_quark, 0, "Couldn't load desktop file:'%s'", path);
g_key_file_free (key_file);
g_free (path);
- return FALSE;
+ return NULL;
}
if (g_key_file_get_boolean (key_file, GROUP_DESKTOP_ENTRY, "Hidden", NULL)) {
- g_debug ("Desktop file is 'hidden', not gathering metadata for it");
+ *error = g_error_new_literal (miner_applications_error_quark, 0, "Desktop file is 'hidden', not gathering metadata for it");
g_key_file_free (key_file);
g_free (path);
- return FALSE;
+ return NULL;
}
- type = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Type", NULL);
+ *type = g_key_file_get_string (key_file, GROUP_DESKTOP_ENTRY, "Type", NULL);
- if (!type) {
+ if (!*type) {
+ *error = g_error_new_literal (miner_applications_error_quark, 0, "Desktop file doesn't contain type");
g_key_file_free (key_file);
- g_free (type);
g_free (path);
+ return NULL;
+ }
+
+ g_free (path);
+
+ return key_file;
+}
+
+static gboolean
+miner_applications_process_file_cb (gpointer user_data)
+{
+ ProcessApplicationData *data = user_data;
+ TrackerSparqlBuilder *sparql;
+ GKeyFile *key_file;
+ gchar *path, *type, *filename, *name = NULL, *uri = NULL;
+ GFileInfo *file_info;
+ GStrv cats = NULL;
+ gsize cats_len;
+ GError *error = NULL;
+
+ sparql = data->sparql;
+ key_file = get_desktop_key_file (data->file, &type, &error);
+
+ if (error) {
+ data->callback (data->miner, data->file, sparql, error, data->callback_data);
+ g_error_free (error);
return FALSE;
}
@@ -236,7 +278,7 @@ miner_applications_process_file (TrackerMinerFS *fs,
} else if (name && g_ascii_strcasecmp (type, "Application") == 0) {
- uri = g_file_get_uri (file);
+ uri = g_file_get_uri (data->file);
tracker_sparql_builder_insert_open (sparql);
tracker_sparql_builder_subject_iri (sparql, APPLICATION_DATASOURCE_URN);
@@ -255,7 +297,7 @@ miner_applications_process_file (TrackerMinerFS *fs,
} else if (name && g_str_has_suffix (type, "Applet")) {
/* The URI of the InformationElement should be a UUID URN */
- uri = g_file_get_uri (file);
+ uri = g_file_get_uri (data->file);
tracker_sparql_builder_insert_open (sparql);
tracker_sparql_builder_subject_iri (sparql, APPLET_DATASOURCE_URN);
@@ -333,12 +375,14 @@ miner_applications_process_file (TrackerMinerFS *fs,
tracker_sparql_builder_predicate (sparql, "nie:dataSource");
tracker_sparql_builder_object_iri (sparql, APPLICATION_DATASOURCE_URN);
+ path = g_file_get_path (data->file);
filename = g_filename_display_basename (path);
tracker_sparql_builder_predicate (sparql, "nfo:fileName");
tracker_sparql_builder_object_string (sparql, filename);
g_free (filename);
+ g_free (path);
- desktop_file_uri = g_file_get_uri (file);
+ desktop_file_uri = g_file_get_uri (data->file);
tracker_sparql_builder_subject_iri (sparql, desktop_file_uri);
tracker_sparql_builder_predicate (sparql, "a");
tracker_sparql_builder_object (sparql, "nfo:FileDataObject");
@@ -350,7 +394,7 @@ miner_applications_process_file (TrackerMinerFS *fs,
}
- file_info = g_file_query_info (file,
+ file_info = g_file_query_info (data->file,
G_FILE_ATTRIBUTE_TIME_MODIFIED,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
NULL, NULL);
@@ -365,6 +409,8 @@ miner_applications_process_file (TrackerMinerFS *fs,
g_object_unref (file_info);
}
+ /* Notify about success */
+ data->callback (data->miner, data->file, sparql, NULL, data->callback_data);
if (cats)
g_strfreev (cats);
@@ -372,9 +418,44 @@ miner_applications_process_file (TrackerMinerFS *fs,
g_free (uri);
g_key_file_free (key_file);
g_free (type);
- g_free (path);
g_free (name);
+ return FALSE;
+}
+
+static void
+process_application_data_free (ProcessApplicationData *data)
+{
+ g_object_unref (data->miner);
+ g_object_unref (data->file);
+ g_object_unref (data->sparql);
+ g_object_unref (data->cancellable);
+ g_slice_free (ProcessApplicationData, data);
+}
+
+static gboolean
+miner_applications_process_file (TrackerMinerFS *fs,
+ GFile *file,
+ TrackerSparqlBuilder *sparql,
+ GCancellable *cancellable,
+ TrackerMinerFSDoneCb done_cb,
+ gpointer done_cb_data)
+{
+ ProcessApplicationData *data;
+
+ data = g_slice_new0 (ProcessApplicationData);
+ 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);
+
+ g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
+ miner_applications_process_file_cb,
+ data,
+ (GDestroyNotify) process_application_data_free);
+
return TRUE;
}
diff --git a/src/tracker-miner-fs/tracker-miner-files.c b/src/tracker-miner-fs/tracker-miner-files.c
index 124dbb7..f5f05a7 100644
--- a/src/tracker-miner-fs/tracker-miner-files.c
+++ b/src/tracker-miner-fs/tracker-miner-files.c
@@ -39,6 +39,16 @@
#define TRACKER_MINER_FILES_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRACKER_TYPE_MINER_FILES, TrackerMinerFilesPrivate))
+typedef struct ProcessFileData ProcessFileData;
+
+struct ProcessFileData {
+ TrackerMinerFiles *miner;
+ TrackerSparqlBuilder *sparql;
+ TrackerMinerFSDoneCb callback;
+ gpointer callback_data;
+ GCancellable *cancellable;
+};
+
struct TrackerMinerFilesPrivate {
TrackerConfig *config;
TrackerStorage *storage;
@@ -92,7 +102,10 @@ static gboolean miner_files_check_directory (TrackerMinerFS *fs,
GFile *file);
static gboolean miner_files_process_file (TrackerMinerFS *fs,
GFile *file,
- TrackerSparqlBuilder *sparql);
+ TrackerSparqlBuilder *sparql,
+ GCancellable *cancellable,
+ TrackerMinerFSDoneCb done_cb,
+ gpointer done_cb_data);
static gboolean miner_files_monitor_directory (TrackerMinerFS *fs,
GFile *file);
@@ -710,35 +723,43 @@ miner_files_add_to_datasource (TrackerMinerFiles *mf,
}
}
-static gboolean
-miner_files_process_file (TrackerMinerFS *fs,
- GFile *file,
- TrackerSparqlBuilder *sparql)
+static void
+free_process_file_data (ProcessFileData *data)
{
- gchar *uri, *mime_type;
+ g_object_unref (data->miner);
+ g_object_unref (data->sparql);
+ g_object_unref (data->cancellable);
+ g_slice_free (ProcessFileData, data);
+}
+
+static void
+process_file_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ TrackerSparqlBuilder *sparql;
+ ProcessFileData *data;
+ const gchar *mime_type;
GFileInfo *file_info;
guint64 time_;
- GFile *parent;
- gchar *parent_uri;
- const gchar *attrs;
-
- attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE ","
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
- G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
- G_FILE_ATTRIBUTE_STANDARD_SIZE ","
- G_FILE_ATTRIBUTE_TIME_MODIFIED ","
- G_FILE_ATTRIBUTE_TIME_ACCESS;
-
- file_info = g_file_query_info (file,
- attrs,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- NULL, NULL);
- if (!file_info) {
- return FALSE;
+ GFile *file, *parent;
+ gchar *uri, *parent_uri;
+ GError *error = NULL;
+
+ data = user_data;
+ file = G_FILE (object);
+ sparql = data->sparql;
+ file_info = g_file_query_info_finish (file, result, &error);
+
+ if (error) {
+ /* Something bad happened, notify about the error */
+ data->callback (TRACKER_MINER_FS (data->miner), file, sparql, error, data->callback_data);
+ free_process_file_data (data);
+ return;
}
uri = g_file_get_uri (file);
- mime_type = g_strdup (g_file_info_get_content_type (file_info));
+ mime_type = g_file_info_get_content_type (file_info);
tracker_sparql_builder_insert_open (sparql);
@@ -780,12 +801,50 @@ miner_files_process_file (TrackerMinerFS *fs,
tracker_sparql_builder_predicate (sparql, "nfo:fileLastAccessed");
tracker_sparql_builder_object_date (sparql, (time_t *) &time_);
- miner_files_add_to_datasource (TRACKER_MINER_FILES (fs), file, sparql);
+ miner_files_add_to_datasource (data->miner, file, sparql);
/* FIXME: Missing embedded data and text */
g_free (uri);
+ /* Notify about the success */
+ data->callback (TRACKER_MINER_FS (data->miner), file, sparql, NULL, data->callback_data);
+ free_process_file_data (data);
+}
+
+static gboolean
+miner_files_process_file (TrackerMinerFS *fs,
+ GFile *file,
+ TrackerSparqlBuilder *sparql,
+ GCancellable *cancellable,
+ TrackerMinerFSDoneCb done_cb,
+ gpointer done_cb_data)
+{
+ 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);
+
+ attrs = G_FILE_ATTRIBUTE_STANDARD_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE ","
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME ","
+ G_FILE_ATTRIBUTE_STANDARD_SIZE ","
+ G_FILE_ATTRIBUTE_TIME_MODIFIED ","
+ G_FILE_ATTRIBUTE_TIME_ACCESS;
+
+ g_file_query_info_async (file,
+ attrs,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ G_PRIORITY_DEFAULT,
+ cancellable,
+ process_file_cb,
+ data);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]