[evolution-data-server] Bug 770452 - Stop using camel_pstring_peek()
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 770452 - Stop using camel_pstring_peek()
- Date: Mon, 29 Aug 2016 16:01:41 +0000 (UTC)
commit ee6813a8df19379ee8b7fcd99ff7af75b8d17782
Author: Hans Petter Jansson <hpj cl no>
Date: Mon Aug 29 18:00:41 2016 +0200
Bug 770452 - Stop using camel_pstring_peek()
If a call to this function results in a string being added to the pool, the
caller effectively owns this initial reference, but it has no way to
distinguish between this and the case where a pointer to an existing string
was returned with no reference added. Thus camel_pstring_free() can never be
called on the result, and any strings that are added this way must stick
around in memory forever.
This is unreasonable for a global string pool that is used to hold a large
number of strings, so avoid using this function.
camel/camel-folder-search.c | 46 ++++++++++++++++++++++++++++++++++++------
1 files changed, 39 insertions(+), 7 deletions(-)
---
diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c
index abf4a34..adbc95a 100644
--- a/camel/camel-folder-search.c
+++ b/camel/camel-folder-search.c
@@ -64,6 +64,17 @@ struct _CamelFolderSearchPrivate {
CamelFolderThread *threads;
GHashTable *threads_hash;
+
+ /* Pointers to strings that were pooled with camel_pstring_strdup()
+ * or camel_pstring_add() during matching, where we own the reference(s).
+ *
+ * A pointer value may occur multiple times, once for each reference held.
+ * These references are released once references have been added to the final
+ * set of matches.
+ *
+ * This saves us having to perform more complex UID life cycle management
+ * and the overhead from the additional refs/unrefs it would require. */
+ GPtrArray *owned_pstrings;
};
typedef enum {
@@ -435,6 +446,7 @@ match_words_index (CamelFolderSearch *search,
GCancellable *cancellable,
GError **error)
{
+ CamelFolderSearchPrivate *p;
GPtrArray *result = g_ptr_array_new ();
struct IterData lambdafoo;
CamelIndexCursor *wc, *nc;
@@ -444,6 +456,10 @@ match_words_index (CamelFolderSearch *search,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return result;
+ p = search->priv;
+
+ g_return_val_if_fail (p->owned_pstrings != NULL, result);
+
/* we can have a maximum of 32 words, as we use it as the AND mask */
wc = camel_index_words (search->body_index);
@@ -457,12 +473,16 @@ match_words_index (CamelFolderSearch *search,
nc = camel_index_find (search->body_index, word);
if (nc) {
while ((name = camel_index_cursor_next (nc))) {
+ gchar *name_owned;
gint mask;
- mask = (GPOINTER_TO_INT (g_hash_table_lookup
(ht, name))) | (1 << i);
+ name_owned = (gchar *) camel_pstring_strdup
(name);
+ g_ptr_array_add (p->owned_pstrings,
name_owned);
+
+ mask = (GPOINTER_TO_INT (g_hash_table_lookup
(ht, name_owned))) | (1 << i);
g_hash_table_insert (
ht,
- (gchar *) camel_pstring_peek (name),
+ name_owned,
GINT_TO_POINTER (mask));
}
g_object_unref (nc);
@@ -1819,6 +1839,16 @@ do_search_in_memory (CamelFolder *search_in_folder,
return !*psql_query;
}
+static void
+free_pstring_array (GPtrArray *array)
+{
+ if (!array)
+ return;
+
+ g_ptr_array_foreach (array, (GFunc) camel_pstring_free, NULL);
+ g_ptr_array_free (array, TRUE);
+}
+
/**
* camel_folder_search_count:
* @search:
@@ -1865,6 +1895,7 @@ camel_folder_search_count (CamelFolderSearch *search,
goto fail;
}
+ p->owned_pstrings = g_ptr_array_new ();
p->cancellable = cancellable;
p->error = error;
@@ -1965,6 +1996,8 @@ fail:
if (search->summary)
camel_folder_free_summary (search->folder, search->summary);
+ free_pstring_array (p->owned_pstrings);
+ p->owned_pstrings = NULL;
p->cancellable = NULL;
p->error = NULL;
p->threads = NULL;
@@ -2022,6 +2055,7 @@ camel_folder_search_search (CamelFolderSearch *search,
goto fail;
}
+ p->owned_pstrings = g_ptr_array_new ();
p->cancellable = cancellable;
p->error = error;
@@ -2140,6 +2174,8 @@ fail:
if (search->summary)
camel_folder_free_summary (search->folder, search->summary);
+ free_pstring_array (p->owned_pstrings);
+ p->owned_pstrings = NULL;
p->cancellable = NULL;
p->error = NULL;
p->threads = NULL;
@@ -2166,11 +2202,7 @@ void
camel_folder_search_free_result (CamelFolderSearch *search,
GPtrArray *result)
{
- if (!result)
- return;
-
- g_ptr_array_foreach (result, (GFunc) camel_pstring_free, NULL);
- g_ptr_array_free (result, TRUE);
+ free_pstring_array (result);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]