[evolution-data-server] Bug #672175 - Make CamelFolderSearch cancellable



commit eee311865a85a42b1453b772d8338d6059f40273
Author: Milan Crha <mcrha redhat com>
Date:   Tue Mar 27 17:12:30 2012 +0200

    Bug #672175 - Make CamelFolderSearch cancellable

 camel/camel-disco-folder.c                 |    2 +-
 camel/camel-folder-search.c                |  143 +++++-----------------------
 camel/camel-folder-search.h                |    6 +-
 camel/camel-folder.c                       |   12 ++-
 camel/camel-folder.h                       |    6 +
 camel/camel-offline-folder.c               |    2 +-
 camel/camel-vee-folder.c                   |   23 +++--
 camel/providers/imap/camel-imap-folder.c   |   15 ++-
 camel/providers/imapx/camel-imapx-folder.c |    9 +-
 camel/providers/local/camel-local-folder.c |    9 +-
 camel/providers/nntp/camel-nntp-folder.c   |    9 +-
 camel/tests/folder/test3.c                 |    2 +-
 camel/tests/folder/test8.c                 |    2 +-
 configure.ac                               |    2 +-
 14 files changed, 85 insertions(+), 157 deletions(-)
---
diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c
index aee5f13..86afde5 100644
--- a/camel/camel-disco-folder.c
+++ b/camel/camel-disco-folder.c
@@ -417,7 +417,7 @@ disco_prepare_for_offline (CamelDiscoFolder *disco_folder,
 		camel_folder_get_full_name (folder));
 
 	if (expression)
-		uids = camel_folder_search_by_expression (folder, expression, error);
+		uids = camel_folder_search_by_expression (folder, expression, cancellable, error);
 	else
 		uids = camel_folder_get_uids (folder);
 
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index 57a9dde..6526995 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -62,6 +62,7 @@
 	((obj), CAMEL_TYPE_FOLDER_SEARCH, CamelFolderSearchPrivate))
 
 struct _CamelFolderSearchPrivate {
+	GCancellable *cancellable;
 	GError **error;
 
 	CamelFolderThread *threads;
@@ -322,113 +323,10 @@ camel_folder_search_set_body_index (CamelFolderSearch *search,
 }
 
 /**
- * camel_folder_search_execute_expression:
- * @search:
- * @expr:
- * @error: return location for a #GError, or %NULL
- *
- * Execute the search expression @expr, returning an array of
- * all matches as a GPtrArray of uid's of matching messages.
- *
- * Note that any settings such as set_body_index(), set_folder(),
- * and so on are reset to %NULL once the search has completed.
- *
- * TODO: The interface should probably return summary items instead
- * (since they are much more useful to any client).
- *
- * Returns: A GPtrArray of strings of all matching messages.
- * This must only be freed by camel_folder_search_free_result.
- **/
-GPtrArray *
-camel_folder_search_execute_expression (CamelFolderSearch *search,
-                                        const gchar *expr,
-                                        GError **error)
-{
-	CamelSExpResult *r;
-	GPtrArray *matches;
-	gint i;
-	GHashTable *results;
-	CamelFolderSearchPrivate *p;
-
-	g_return_val_if_fail (search != NULL, NULL);
-
-	p = search->priv;
-	p->error = error;
-
-	/* only re-parse if the search has changed */
-	if (search->last_search == NULL
-	    || strcmp (search->last_search, expr)) {
-		camel_sexp_input_text (search->sexp, expr, strlen (expr));
-		if (camel_sexp_parse (search->sexp) == -1) {
-			g_set_error (
-				error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-				_("Cannot parse search expression: %s:\n%s"),
-				camel_sexp_error (search->sexp), expr);
-			return NULL;
-		}
-
-		g_free (search->last_search);
-		search->last_search = g_strdup (expr);
-	}
-	r = camel_sexp_eval (search->sexp);
-	if (r == NULL) {
-		g_set_error (
-			error, CAMEL_ERROR, CAMEL_ERROR_GENERIC,
-			_("Error executing search expression: %s:\n%s"),
-			camel_sexp_error (search->sexp), expr);
-		return NULL;
-	}
-
-	matches = g_ptr_array_new ();
-
-	/* now create a folder summary to return?? */
-	if (r->type == CAMEL_SEXP_RES_ARRAY_PTR) {
-		d(printf("got result ...\n"));
-		if (search->summary) {
-			/* reorder result in summary order */
-			results = g_hash_table_new (g_str_hash, g_str_equal);
-			for (i = 0; i < r->value.ptrarray->len; i++) {
-				d(printf("adding match: %s\n", (gchar *)g_ptr_array_index(r->value.ptrarray, i)));
-				g_hash_table_insert (results, g_ptr_array_index (r->value.ptrarray, i), GINT_TO_POINTER (1));
-			}
-			for (i = 0; i < search->summary->len; i++) {
-				gchar *uid = g_ptr_array_index (search->summary, i);
-				if (g_hash_table_lookup (results, uid)) {
-					g_ptr_array_add (matches, (gpointer) camel_pstring_strdup (uid));
-				}
-			}
-			g_hash_table_destroy (results);
-		} else {
-			for (i = 0; i < r->value.ptrarray->len; i++) {
-				d(printf("adding match: %s\n", (gchar *)g_ptr_array_index(r->value.ptrarray, i)));
-				g_ptr_array_add (matches, (gpointer) camel_pstring_strdup (g_ptr_array_index (r->value.ptrarray, i)));
-			}
-		}
-	} else {
-		g_warning("Search returned an invalid result type");
-	}
-
-	camel_sexp_result_free (search->sexp, r);
-
-	if (p->threads)
-		camel_folder_thread_messages_unref (p->threads);
-	if (p->threads_hash)
-		g_hash_table_destroy (p->threads_hash);
-
-	p->threads = NULL;
-	p->threads_hash = NULL;
-	search->folder = NULL;
-	search->summary = NULL;
-	search->current = NULL;
-	search->body_index = NULL;
-
-	return matches;
-}
-
-/**
  * camel_folder_search_count:
  * @search:
  * @expr:
+ * @cancellable: a #GCancellable
  * @error: return location for a #GError, or %NULL
  *
  * Run a search.  Search must have had Folder already set on it, and
@@ -442,6 +340,7 @@ camel_folder_search_execute_expression (CamelFolderSearch *search,
 guint32
 camel_folder_search_count (CamelFolderSearch *search,
                            const gchar *expr,
+			   GCancellable *cancellable,
                            GError **error)
 {
 	CamelSExpResult *r;
@@ -460,6 +359,7 @@ camel_folder_search_count (CamelFolderSearch *search,
 
 	g_assert (search->folder);
 
+	p->cancellable = cancellable;
 	p->error = error;
 
 	/* We route body-contains search and thread based search through memory and not via db. */
@@ -561,6 +461,8 @@ fail:
 	if (search->summary)
 		camel_folder_free_summary (search->folder, search->summary);
 
+	p->cancellable = NULL;
+	p->error = NULL;
 	p->threads = NULL;
 	p->threads_hash = NULL;
 	search->folder = NULL;
@@ -605,6 +507,7 @@ do_search_in_memory (const gchar *expr)
  * @search:
  * @expr:
  * @uids: to search against, NULL for all uid's.
+ * @cancellable: a #GCancellable
  * @error: return location for a #GError, or %NULL
  *
  * Run a search.  Search must have had Folder already set on it, and
@@ -616,6 +519,7 @@ GPtrArray *
 camel_folder_search_search (CamelFolderSearch *search,
                             const gchar *expr,
                             GPtrArray *uids,
+			    GCancellable *cancellable,
                             GError **error)
 {
 	CamelSExpResult *r;
@@ -633,6 +537,7 @@ camel_folder_search_search (CamelFolderSearch *search,
 
 	g_assert (search->folder);
 
+	p->cancellable = cancellable;
 	p->error = error;
 
 	/* We route body-contains / thread based search and uid search through memory and not via db. */
@@ -752,6 +657,8 @@ fail:
 	if (search->summary)
 		camel_folder_free_summary (search->folder, search->summary);
 
+	p->cancellable = NULL;
+	p->error = NULL;
 	p->threads = NULL;
 	p->threads_hash = NULL;
 	search->folder = NULL;
@@ -914,7 +821,7 @@ search_match_all (struct _CamelSExp *f,
 		camel_folder_summary_prepare_fetch_all (search->folder->summary, search->priv->error);
 	}
 
-	for (i = 0; i < v->len; i++) {
+	for (i = 0; i < v->len && !g_cancellable_is_cancelled (search->priv->cancellable); i++) {
 		const gchar *uid;
 
 		search->current = camel_folder_summary_get (search->folder->summary, v->pdata[i]);
@@ -1105,9 +1012,8 @@ get_current_message (CamelFolderSearch *search)
 	if (!search || !search->folder || !search->current)
 		return NULL;
 
-	/* FIXME Pass a GCancellable */
 	return camel_folder_get_message_sync (
-		search->folder, search->current->uid, NULL, NULL);
+		search->folder, search->current->uid, search->priv->cancellable, NULL);
 }
 
 static CamelSExpResult *
@@ -1496,7 +1402,8 @@ match_words_index (CamelFolderSearch *search,
 static gboolean
 match_words_1message (CamelDataWrapper *object,
                       struct _camel_search_words *words,
-                      guint32 *mask)
+                      guint32 *mask,
+		      GCancellable *cancellable)
 {
 	CamelDataWrapper *containee;
 	gint truth = FALSE;
@@ -1513,11 +1420,11 @@ match_words_1message (CamelDataWrapper *object,
 		for (i = 0; i < parts && truth == FALSE; i++) {
 			CamelDataWrapper *part = (CamelDataWrapper *) camel_multipart_get_part (CAMEL_MULTIPART (containee), i);
 			if (part)
-				truth = match_words_1message (part, words, mask);
+				truth = match_words_1message (part, words, mask, cancellable);
 		}
 	} else if (CAMEL_IS_MIME_MESSAGE (containee)) {
 		/* for messages we only look at its contents */
-		truth = match_words_1message ((CamelDataWrapper *) containee, words, mask);
+		truth = match_words_1message ((CamelDataWrapper *) containee, words, mask, cancellable);
 	} else if (camel_content_type_is(CAMEL_DATA_WRAPPER (containee)->mime_type, "text", "*")) {
 		/* for all other text parts, we look inside, otherwise we dont care */
 		CamelStream *stream;
@@ -1527,9 +1434,8 @@ match_words_1message (CamelDataWrapper *object,
 		stream = camel_stream_mem_new_with_byte_array (byte_array);
 
 		/* FIXME The match should be part of a stream op */
-		/* FIXME Pass a GCancellable and GError here. */
 		camel_data_wrapper_decode_to_stream_sync (
-			containee, stream, NULL, NULL);
+			containee, stream, cancellable, NULL);
 		camel_stream_write (stream, "", 1, NULL, NULL);
 		for (i = 0; i < words->len; i++) {
 			/* FIXME: This is horridly slow, and should use a real search algorithm */
@@ -1561,7 +1467,7 @@ match_words_message (CamelFolder *folder,
 	msg = camel_folder_get_message_sync (folder, uid, cancellable, error);
 	if (msg) {
 		mask = 0;
-		truth = match_words_1message ((CamelDataWrapper *) msg, words, &mask);
+		truth = match_words_1message ((CamelDataWrapper *) msg, words, &mask, cancellable);
 		g_object_unref (msg);
 	}
 
@@ -1638,8 +1544,7 @@ search_body_contains (struct _CamelSExp *f,
 							truth = match_message_index (search->body_index, camel_message_info_uid (search->current), words->words[j]->word, error);
 					} else {
 						/* TODO: cache current message incase of multiple body search terms */
-						/* FIXME Pass a GCancellable */
-						truth = match_words_message (search->folder, camel_message_info_uid (search->current), words, NULL, error);
+						truth = match_words_message (search->folder, camel_message_info_uid (search->current), words, search->priv->cancellable, error);
 					}
 					camel_search_words_free (words);
 				}
@@ -1669,8 +1574,7 @@ search_body_contains (struct _CamelSExp *f,
 					if ((words->type & CAMEL_SEARCH_WORD_COMPLEX) == 0 && search->body_index) {
 						matches = match_words_index (search, words, error);
 					} else {
-						/* FIXME Pass a GCancellable */
-						matches = match_words_messages (search, words, NULL, error);
+						matches = match_words_messages (search, words, search->priv->cancellable, error);
 					}
 					for (j = 0; j < matches->len; j++) {
 						g_hash_table_insert (ht, matches->pdata[j], matches->pdata[j]);
@@ -1720,12 +1624,11 @@ search_body_regex (struct _CamelSExp *f,
 			GPtrArray *v = search->summary_set ? search->summary_set : search->summary;
 			CamelMimeMessage *message;
 
-			for (i = 0; i < v->len; i++) {
+			for (i = 0; i < v->len && !g_cancellable_is_cancelled (search->priv->cancellable); i++) {
 				gchar *uid = g_ptr_array_index (v, i);
 
-				/* FIXME Pass a GCancellable */
 				message = camel_folder_get_message_sync (
-					search->folder, uid, NULL, NULL);
+					search->folder, uid, search->priv->cancellable, NULL);
 				if (message) {
 					if (camel_search_message_body_contains ((CamelDataWrapper *) message, &pattern)) {
 						g_ptr_array_add (r->value.ptrarray, uid);
diff --git a/camel/camel-folder-search.h b/camel/camel-folder-search.h
index b3a7a4a..58f5ac1 100644
--- a/camel/camel-folder-search.h
+++ b/camel/camel-folder-search.h
@@ -159,11 +159,9 @@ void camel_folder_search_construct (CamelFolderSearch *search);
 void camel_folder_search_set_folder (CamelFolderSearch *search, CamelFolder *folder);
 void camel_folder_search_set_summary (CamelFolderSearch *search, GPtrArray *summary);
 void camel_folder_search_set_body_index (CamelFolderSearch *search, CamelIndex *body_index);
-/* this interface is deprecated */
-GPtrArray *camel_folder_search_execute_expression (CamelFolderSearch *search, const gchar *expr, GError **error);
 
-GPtrArray *camel_folder_search_search (CamelFolderSearch *search, const gchar *expr, GPtrArray *uids, GError **error);
-guint32 camel_folder_search_count (CamelFolderSearch *search, const gchar *expr, GError **error);
+GPtrArray *camel_folder_search_search (CamelFolderSearch *search, const gchar *expr, GPtrArray *uids, GCancellable *cancellable, GError **error);
+guint32 camel_folder_search_count (CamelFolderSearch *search, const gchar *expr, GCancellable *cancellable, GError **error);
 void camel_folder_search_free_result (CamelFolderSearch *search, GPtrArray *);
 
 time_t camel_folder_search_util_add_months (time_t t, gint months);
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index fc0957b..d73bf11 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -2627,6 +2627,7 @@ camel_folder_has_search_capability (CamelFolder *folder)
  * camel_folder_search_by_expression:
  * @folder: a #CamelFolder
  * @expr: a search expression
+ * @cancellable: a #GCancellable
  * @error: return location for a #GError, or %NULL
  *
  * Searches the folder for messages matching the given search expression.
@@ -2637,6 +2638,7 @@ camel_folder_has_search_capability (CamelFolder *folder)
 GPtrArray *
 camel_folder_search_by_expression (CamelFolder *folder,
                                    const gchar *expression,
+				   GCancellable *cancellable,
                                    GError **error)
 {
 	CamelFolderClass *class;
@@ -2650,7 +2652,7 @@ camel_folder_search_by_expression (CamelFolder *folder,
 
 	/* NOTE: that it is upto the callee to CAMEL_FOLDER_REC_LOCK */
 
-	matches = class->search_by_expression (folder, expression, error);
+	matches = class->search_by_expression (folder, expression, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, search_by_expression, matches != NULL, error);
 
 	return matches;
@@ -2660,6 +2662,7 @@ camel_folder_search_by_expression (CamelFolder *folder,
  * camel_folder_count_by_expression:
  * @folder: a #CamelFolder
  * @expression: a search expression
+ * @cancellable: a #GCancellable
  * @error: return location for a #GError, or %NULL
  *
  * Searches the folder for count of messages matching the given search expression.
@@ -2671,6 +2674,7 @@ camel_folder_search_by_expression (CamelFolder *folder,
 guint32
 camel_folder_count_by_expression (CamelFolder *folder,
                                   const gchar *expression,
+				  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelFolderClass *class;
@@ -2683,7 +2687,7 @@ camel_folder_count_by_expression (CamelFolder *folder,
 
 	/* NOTE: that it is upto the callee to CAMEL_FOLDER_REC_LOCK */
 
-	return class->count_by_expression (folder, expression, error);
+	return class->count_by_expression (folder, expression, cancellable, error);
 }
 
 /**
@@ -2691,6 +2695,7 @@ camel_folder_count_by_expression (CamelFolder *folder,
  * @folder: a #CamelFolder
  * @expr: search expression
  * @uids: array of uid's to match against.
+ * @cancellable: a #GCancellable
  * @error: return location for a #GError, or %NULL
  *
  * Search a subset of uid's for an expression match.
@@ -2702,6 +2707,7 @@ GPtrArray *
 camel_folder_search_by_uids (CamelFolder *folder,
                              const gchar *expr,
                              GPtrArray *uids,
+			     GCancellable *cancellable,
                              GError **error)
 {
 	CamelFolderClass *class;
@@ -2715,7 +2721,7 @@ camel_folder_search_by_uids (CamelFolder *folder,
 
 	/* NOTE: that it is upto the callee to CAMEL_FOLDER_REC_LOCK */
 
-	matches = class->search_by_uids (folder, expr, uids, error);
+	matches = class->search_by_uids (folder, expr, uids, cancellable, error);
 	CAMEL_CHECK_GERROR (folder, search_by_uids, matches != NULL, error);
 
 	return matches;
diff --git a/camel/camel-folder.h b/camel/camel-folder.h
index e249309..f289146 100644
--- a/camel/camel-folder.h
+++ b/camel/camel-folder.h
@@ -185,10 +185,12 @@ struct _CamelFolderClass {
 	gboolean	(*has_search_capability)(CamelFolder *folder);
 	GPtrArray *	(*search_by_expression)	(CamelFolder *folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 	GPtrArray *	(*search_by_uids)	(CamelFolder *folder,
 						 const gchar *expression,
 						 GPtrArray *uids,
+						 GCancellable *cancellable,
 						 GError **error);
 	void		(*search_free)		(CamelFolder *folder,
 						 GPtrArray *result);
@@ -207,6 +209,7 @@ struct _CamelFolderClass {
 	gboolean	(*is_frozen)		(CamelFolder *folder);
 	guint32		(*count_by_expression)	(CamelFolder *folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 	GPtrArray *	(*get_uncached_uids)	(CamelFolder *folder,
 						 GPtrArray *uids,
@@ -463,15 +466,18 @@ gboolean	camel_folder_has_search_capability
 GPtrArray *	camel_folder_search_by_expression
 						(CamelFolder *folder,
 						 const gchar *expr,
+						 GCancellable *cancellable,
 						 GError **error);
 GPtrArray *	camel_folder_search_by_uids	(CamelFolder *folder,
 						 const gchar *expr,
 						 GPtrArray *uids,
+						 GCancellable *cancellable,
 						 GError **error);
 void		camel_folder_search_free	(CamelFolder *folder,
 						 GPtrArray *result);
 guint32		camel_folder_count_by_expression (CamelFolder *folder,
 						 const gchar *expression,
+						 GCancellable *cancellable,
 						 GError **error);
 CamelMessageInfo *
 		camel_folder_get_message_info	(CamelFolder *folder,
diff --git a/camel/camel-offline-folder.c b/camel/camel-offline-folder.c
index 0f16d7b..7e52bbc 100644
--- a/camel/camel-offline-folder.c
+++ b/camel/camel-offline-folder.c
@@ -207,7 +207,7 @@ offline_folder_downsync_sync (CamelOfflineFolder *offline,
 		camel_folder_get_full_name (folder));
 
 	if (expression)
-		uids = camel_folder_search_by_expression (folder, expression, NULL);
+		uids = camel_folder_search_by_expression (folder, expression, cancellable, NULL);
 	else
 		uids = camel_folder_get_uids (folder);
 
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index ba674cb..e1df20a 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -378,7 +378,7 @@ folder_changed_change (CamelVeeFolder *vf,
 	/* Find newly added that match */
 	if (changes->uid_added->len > 0) {
 		dd (printf (" Searching for added matches '%s'\n", vf->expression));
-		matches_added = camel_folder_search_by_uids (sub, vf->expression, changes->uid_added, NULL);
+		matches_added = camel_folder_search_by_uids (sub, vf->expression, changes->uid_added, cancellable, NULL);
 	}
 
 	/* TODO:
@@ -413,9 +413,9 @@ folder_changed_change (CamelVeeFolder *vf,
 		}
 
 		if (changed->len)
-			matches_changed = camel_folder_search_by_uids (sub, vf->expression, changed, NULL);
+			matches_changed = camel_folder_search_by_uids (sub, vf->expression, changed, cancellable, NULL);
 		if (always_changed && always_changed->len)
-			present = camel_folder_search_by_uids (sub, vf->expression, always_changed, NULL);
+			present = camel_folder_search_by_uids (sub, vf->expression, always_changed, cancellable, NULL);
 	}
 
 	camel_vee_folder_lock (vf, CAMEL_VEE_FOLDER_SUMMARY_LOCK);
@@ -1082,6 +1082,7 @@ vee_folder_propagate_skipped_changes (CamelVeeFolder *vf)
 static GPtrArray *
 vee_folder_search_by_expression (CamelFolder *folder,
                                  const gchar *expression,
+				 GCancellable *cancellable,
                                  GError **error)
 {
 	GList *node;
@@ -1104,7 +1105,7 @@ vee_folder_search_by_expression (CamelFolder *folder,
 	}
 
 	node = p->folders;
-	while (node) {
+	while (node && !g_cancellable_is_cancelled (cancellable)) {
 		CamelFolder *f = node->data;
 		gint i;
 		gchar hash[8];
@@ -1112,7 +1113,7 @@ vee_folder_search_by_expression (CamelFolder *folder,
 		/* make sure we only search each folder once - for unmatched folder to work right */
 		if (g_hash_table_lookup (searched, f) == NULL) {
 			camel_vee_folder_hash_folder (f, hash);
-			matches = camel_folder_search_by_expression (f, expr, NULL);
+			matches = camel_folder_search_by_expression (f, expr, cancellable, NULL);
 			if (matches) {
 				for (i = 0; i < matches->len; i++) {
 					gchar *uid = matches->pdata[i], *vuid;
@@ -1143,6 +1144,7 @@ static GPtrArray *
 vee_folder_search_by_uids (CamelFolder *folder,
                            const gchar *expression,
                            GPtrArray *uids,
+			   GCancellable *cancellable,
                            GError **error)
 {
 	GList *node;
@@ -1159,7 +1161,7 @@ vee_folder_search_by_uids (CamelFolder *folder,
 
 	expr = g_strdup_printf ("(and %s %s)", vf->expression ? vf->expression : "", expression);
 	node = p->folders;
-	while (node) {
+	while (node && !g_cancellable_is_cancelled (cancellable)) {
 		CamelFolder *f = node->data;
 		gint i;
 		gchar hash[8];
@@ -1177,7 +1179,7 @@ vee_folder_search_by_uids (CamelFolder *folder,
 					g_ptr_array_add (folder_uids, uid + 8);
 			}
 			if (folder_uids->len > 0) {
-				matches = camel_folder_search_by_uids (f, expr, folder_uids, error);
+				matches = camel_folder_search_by_uids (f, expr, folder_uids, cancellable, error);
 				if (matches) {
 					for (i = 0; i < matches->len; i++) {
 						gchar *uid = matches->pdata[i], *vuid;
@@ -1208,6 +1210,7 @@ vee_folder_search_by_uids (CamelFolder *folder,
 static guint32
 vee_folder_count_by_expression (CamelFolder *folder,
                                 const gchar *expression,
+				GCancellable *cancellable,
                                 GError **error)
 {
 	GList *node;
@@ -1226,12 +1229,12 @@ vee_folder_count_by_expression (CamelFolder *folder,
 		expr = g_strdup (expression);
 
 	node = p->folders;
-	while (node) {
+	while (node && !g_cancellable_is_cancelled (cancellable)) {
 		CamelFolder *f = node->data;
 
 		/* make sure we only search each folder once - for unmatched folder to work right */
 		if (g_hash_table_lookup (searched, f) == NULL) {
-			count += camel_folder_count_by_expression (f, expr, NULL);
+			count += camel_folder_count_by_expression (f, expr, cancellable, NULL);
 			g_hash_table_insert (searched, f, f);
 		}
 		node = g_list_next (node);
@@ -1740,7 +1743,7 @@ vee_folder_rebuild_folder (CamelVeeFolder *vee_folder,
 			/* We take this to mean the results have not been cached.
 			 * XXX: It will also trigger if the result set is empty. */
 			match == NULL) {
-			match = camel_folder_search_by_expression (source, vee_folder->expression, error);
+			match = camel_folder_search_by_expression (source, vee_folder->expression, NULL, error);
 			if (match == NULL) /* Search failed */
 				return 0;
 			rebuilded = TRUE;
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index a0aeda1..5cfb735 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -114,9 +114,9 @@ static gboolean	imap_transfer_offline		(CamelFolder *source,
 						 GError **error);
 
 /* searching */
-static GPtrArray *imap_search_by_expression (CamelFolder *folder, const gchar *expression, GError **error);
-static guint32 imap_count_by_expression (CamelFolder *folder, const gchar *expression, GError **error);
-static GPtrArray *imap_search_by_uids	    (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GError **error);
+static GPtrArray *imap_search_by_expression (CamelFolder *folder, const gchar *expression, GCancellable *cancellable, GError **error);
+static guint32 imap_count_by_expression (CamelFolder *folder, const gchar *expression, GCancellable *cancellable, GError **error);
+static GPtrArray *imap_search_by_uids	    (CamelFolder *folder, const gchar *expression, GPtrArray *uids, GCancellable *cancellable, GError **error);
 static void       imap_search_free          (CamelFolder *folder, GPtrArray *uids);
 
 static void imap_thaw (CamelFolder *folder);
@@ -3074,6 +3074,7 @@ camel_imap_transfer_resyncing (CamelFolder *source,
 static GPtrArray *
 imap_search_by_expression (CamelFolder *folder,
                            const gchar *expression,
+			   GCancellable *cancellable,
                            GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -3085,7 +3086,7 @@ imap_search_by_expression (CamelFolder *folder,
 	CAMEL_IMAP_FOLDER_LOCK (folder, search_lock);
 
 	camel_folder_search_set_folder (imap_folder->search, folder);
-	matches = camel_folder_search_search (imap_folder->search, expression, NULL, error);
+	matches = camel_folder_search_search (imap_folder->search, expression, NULL, cancellable, error);
 
 	CAMEL_IMAP_FOLDER_UNLOCK (folder, search_lock);
 
@@ -3095,6 +3096,7 @@ imap_search_by_expression (CamelFolder *folder,
 static guint32
 imap_count_by_expression (CamelFolder *folder,
                           const gchar *expression,
+			  GCancellable *cancellable,
                           GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -3106,7 +3108,7 @@ imap_count_by_expression (CamelFolder *folder,
 	CAMEL_IMAP_FOLDER_LOCK (folder, search_lock);
 
 	camel_folder_search_set_folder (imap_folder->search, folder);
-	matches = camel_folder_search_count (imap_folder->search, expression, error);
+	matches = camel_folder_search_count (imap_folder->search, expression, cancellable, error);
 
 	CAMEL_IMAP_FOLDER_UNLOCK (folder, search_lock);
 
@@ -3117,6 +3119,7 @@ static GPtrArray *
 imap_search_by_uids (CamelFolder *folder,
                      const gchar *expression,
                      GPtrArray *uids,
+		     GCancellable *cancellable,
                      GError **error)
 {
 	CamelImapFolder *imap_folder = CAMEL_IMAP_FOLDER (folder);
@@ -3128,7 +3131,7 @@ imap_search_by_uids (CamelFolder *folder,
 	CAMEL_IMAP_FOLDER_LOCK (folder, search_lock);
 
 	camel_folder_search_set_folder (imap_folder->search, folder);
-	matches = camel_folder_search_search (imap_folder->search, expression, uids, error);
+	matches = camel_folder_search_search (imap_folder->search, expression, uids, cancellable, error);
 
 	CAMEL_IMAP_FOLDER_UNLOCK (folder, search_lock);
 
diff --git a/camel/providers/imapx/camel-imapx-folder.c b/camel/providers/imapx/camel-imapx-folder.c
index f73fe70..d9c4c21 100644
--- a/camel/providers/imapx/camel-imapx-folder.c
+++ b/camel/providers/imapx/camel-imapx-folder.c
@@ -330,6 +330,7 @@ static GPtrArray *
 imapx_search_by_uids (CamelFolder *folder,
                       const gchar *expression,
                       GPtrArray *uids,
+		      GCancellable *cancellable,
                       GError **error)
 {
 	CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER (folder);
@@ -341,7 +342,7 @@ imapx_search_by_uids (CamelFolder *folder,
 	g_mutex_lock (ifolder->search_lock);
 
 	camel_folder_search_set_folder (ifolder->search, folder);
-	matches = camel_folder_search_search (ifolder->search, expression, uids, error);
+	matches = camel_folder_search_search (ifolder->search, expression, uids, cancellable, error);
 
 	g_mutex_unlock (ifolder->search_lock);
 
@@ -351,6 +352,7 @@ imapx_search_by_uids (CamelFolder *folder,
 static guint32
 imapx_count_by_expression (CamelFolder *folder,
                            const gchar *expression,
+			   GCancellable *cancellable,
                            GError **error)
 {
 	CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER (folder);
@@ -359,7 +361,7 @@ imapx_count_by_expression (CamelFolder *folder,
 	g_mutex_lock (ifolder->search_lock);
 
 	camel_folder_search_set_folder (ifolder->search, folder);
-	matches = camel_folder_search_count (ifolder->search, expression, error);
+	matches = camel_folder_search_count (ifolder->search, expression, cancellable, error);
 
 	g_mutex_unlock (ifolder->search_lock);
 
@@ -369,6 +371,7 @@ imapx_count_by_expression (CamelFolder *folder,
 static GPtrArray *
 imapx_search_by_expression (CamelFolder *folder,
                             const gchar *expression,
+			    GCancellable *cancellable,
                             GError **error)
 {
 	CamelIMAPXFolder *ifolder = CAMEL_IMAPX_FOLDER (folder);
@@ -377,7 +380,7 @@ imapx_search_by_expression (CamelFolder *folder,
 	g_mutex_lock (ifolder->search_lock);
 
 	camel_folder_search_set_folder (ifolder->search, folder);
-	matches = camel_folder_search_search (ifolder->search, expression, NULL, error);
+	matches = camel_folder_search_search (ifolder->search, expression, NULL, cancellable, error);
 
 	g_mutex_unlock (ifolder->search_lock);
 
diff --git a/camel/providers/local/camel-local-folder.c b/camel/providers/local/camel-local-folder.c
index b62975a..47c275f 100644
--- a/camel/providers/local/camel-local-folder.c
+++ b/camel/providers/local/camel-local-folder.c
@@ -228,6 +228,7 @@ local_folder_constructed (GObject *object)
 static GPtrArray *
 local_folder_search_by_expression (CamelFolder *folder,
                                    const gchar *expression,
+				   GCancellable *cancellable,
                                    GError **error)
 {
 	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
@@ -243,7 +244,7 @@ local_folder_search_by_expression (CamelFolder *folder,
 		camel_folder_search_set_body_index (local_folder->search, local_folder->index);
 	else
 		camel_folder_search_set_body_index (local_folder->search, NULL);
-	matches = camel_folder_search_search (local_folder->search, expression, NULL, error);
+	matches = camel_folder_search_search (local_folder->search, expression, NULL, cancellable, error);
 
 	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
 
@@ -254,6 +255,7 @@ static GPtrArray *
 local_folder_search_by_uids (CamelFolder *folder,
                              const gchar *expression,
                              GPtrArray *uids,
+			     GCancellable *cancellable,
                              GError **error)
 {
 	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
@@ -272,7 +274,7 @@ local_folder_search_by_uids (CamelFolder *folder,
 		camel_folder_search_set_body_index (local_folder->search, local_folder->index);
 	else
 		camel_folder_search_set_body_index (local_folder->search, NULL);
-	matches = camel_folder_search_search (local_folder->search, expression, uids, error);
+	matches = camel_folder_search_search (local_folder->search, expression, uids, cancellable, error);
 
 	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
 
@@ -340,6 +342,7 @@ local_folder_rename (CamelFolder *folder,
 static guint32
 local_folder_count_by_expression (CamelFolder *folder,
                                   const gchar *expression,
+				  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelLocalFolder *local_folder = CAMEL_LOCAL_FOLDER (folder);
@@ -355,7 +358,7 @@ local_folder_count_by_expression (CamelFolder *folder,
 		camel_folder_search_set_body_index (local_folder->search, local_folder->index);
 	else
 		camel_folder_search_set_body_index (local_folder->search, NULL);
-	matches = camel_folder_search_count (local_folder->search, expression, error);
+	matches = camel_folder_search_count (local_folder->search, expression, cancellable, error);
 
 	CAMEL_LOCAL_FOLDER_UNLOCK (folder, search_lock);
 
diff --git a/camel/providers/nntp/camel-nntp-folder.c b/camel/providers/nntp/camel-nntp-folder.c
index b557ebc..98098bc 100644
--- a/camel/providers/nntp/camel-nntp-folder.c
+++ b/camel/providers/nntp/camel-nntp-folder.c
@@ -398,6 +398,7 @@ nntp_folder_cache_message (CamelDiscoFolder *disco_folder,
 static GPtrArray *
 nntp_folder_search_by_expression (CamelFolder *folder,
                                   const gchar *expression,
+				  GCancellable *cancellable,
                                   GError **error)
 {
 	CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
@@ -409,7 +410,7 @@ nntp_folder_search_by_expression (CamelFolder *folder,
 		nntp_folder->search = camel_folder_search_new ();
 
 	camel_folder_search_set_folder (nntp_folder->search, folder);
-	matches = camel_folder_search_search (nntp_folder->search, expression, NULL, error);
+	matches = camel_folder_search_search (nntp_folder->search, expression, NULL, cancellable, error);
 
 	CAMEL_NNTP_FOLDER_UNLOCK (nntp_folder, search_lock);
 
@@ -419,6 +420,7 @@ nntp_folder_search_by_expression (CamelFolder *folder,
 static guint32
 nntp_folder_count_by_expression (CamelFolder *folder,
                                  const gchar *expression,
+				 GCancellable *cancellable,
                                  GError **error)
 {
 	CamelNNTPFolder *nntp_folder = CAMEL_NNTP_FOLDER (folder);
@@ -430,7 +432,7 @@ nntp_folder_count_by_expression (CamelFolder *folder,
 		nntp_folder->search = camel_folder_search_new ();
 
 	camel_folder_search_set_folder (nntp_folder->search, folder);
-	count = camel_folder_search_count (nntp_folder->search, expression, error);
+	count = camel_folder_search_count (nntp_folder->search, expression, cancellable, error);
 
 	CAMEL_NNTP_FOLDER_UNLOCK (nntp_folder, search_lock);
 
@@ -441,6 +443,7 @@ static GPtrArray *
 nntp_folder_search_by_uids (CamelFolder *folder,
                             const gchar *expression,
                             GPtrArray *uids,
+			    GCancellable *cancellable,
                             GError **error)
 {
 	CamelNNTPFolder *nntp_folder = (CamelNNTPFolder *) folder;
@@ -455,7 +458,7 @@ nntp_folder_search_by_uids (CamelFolder *folder,
 		nntp_folder->search = camel_folder_search_new ();
 
 	camel_folder_search_set_folder (nntp_folder->search, folder);
-	matches = camel_folder_search_search (nntp_folder->search, expression, uids, error);
+	matches = camel_folder_search_search (nntp_folder->search, expression, uids, cancellable, error);
 
 	CAMEL_NNTP_FOLDER_UNLOCK (folder, search_lock);
 
diff --git a/camel/tests/folder/test3.c b/camel/tests/folder/test3.c
index 31e906d..d02378a 100644
--- a/camel/tests/folder/test3.c
+++ b/camel/tests/folder/test3.c
@@ -18,7 +18,7 @@ test_folder_search_sub (CamelFolder *folder,
 	gint i;
 	GError *error = NULL;
 
-	uids = camel_folder_search_by_expression (folder, expr, &error);
+	uids = camel_folder_search_by_expression (folder, expr, NULL, &error);
 	check (uids != NULL);
 	check_msg (uids->len == expected, "search %s expected %d got %d", expr, expected, uids->len);
 	check_msg (error == NULL, "%s", error->message);
diff --git a/camel/tests/folder/test8.c b/camel/tests/folder/test8.c
index 4fc91d7..2eef068 100644
--- a/camel/tests/folder/test8.c
+++ b/camel/tests/folder/test8.c
@@ -71,7 +71,7 @@ worker (gpointer d)
 		sub = g_strdup_printf ("(match-all (header-contains \"subject\" \"message %08x subject\"))", id+i);
 
 		push ("searching for message %d\n\tusing: %s", id+i, sub);
-		res = camel_folder_search_by_expression (info->folder, sub, &error);
+		res = camel_folder_search_by_expression (info->folder, sub, NULL, &error);
 		check_msg (error == NULL, "%s", error->message);
 		check_msg (res->len == 1, "res->len = %d", res->len);
 		g_clear_error (&error);
diff --git a/configure.ac b/configure.ac
index a4853d9..d9a9e33 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,7 +103,7 @@ LIBEBOOK_CURRENT=16
 LIBEBOOK_REVISION=1
 LIBEBOOK_AGE=3
 
-LIBCAMEL_CURRENT=33
+LIBCAMEL_CURRENT=34
 LIBCAMEL_REVISION=0
 LIBCAMEL_AGE=0
 



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