[evolution-data-server] Avoid camel_store_summary_index().
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Avoid camel_store_summary_index().
- Date: Fri, 16 Aug 2013 18:07:24 +0000 (UTC)
commit c23a9b0842d98430f4585ec5e83358acbf18d310
Author: Matthew Barnes <mbarnes redhat com>
Date: Fri Aug 16 12:23:28 2013 -0400
Avoid camel_store_summary_index().
camel_store_summary_index() is only called when looping over summary
items from 0 to camel_store_summary_count(). But this pattern is not
thread-safe, because another thread could add or remove summary items
while the loop is in progress.
Use camel_store_summary_array() instead to avoid these issues.
camel/camel-imapx-store-summary.c | 46 ++++++---
camel/camel-imapx-store.c | 130 ++++++++++++-----------
camel/providers/nntp/camel-nntp-store-summary.c | 30 ++++--
camel/providers/nntp/camel-nntp-store.c | 127 ++++++++++++----------
4 files changed, 189 insertions(+), 144 deletions(-)
---
diff --git a/camel/camel-imapx-store-summary.c b/camel/camel-imapx-store-summary.c
index 95674af..d921fb2 100644
--- a/camel/camel-imapx-store-summary.c
+++ b/camel/camel-imapx-store-summary.c
@@ -120,24 +120,40 @@ CamelIMAPXStoreInfo *
camel_imapx_store_summary_full_name (CamelIMAPXStoreSummary *s,
const gchar *full_name)
{
- gint count, i;
- CamelIMAPXStoreInfo *info;
- gboolean is_inbox;
-
- is_inbox = camel_imapx_mailbox_is_inbox (full_name);
-
- count = camel_store_summary_count ((CamelStoreSummary *) s);
- for (i = 0; i < count; i++) {
- info = (CamelIMAPXStoreInfo *) camel_store_summary_index ((CamelStoreSummary *) s, i);
- if (info) {
- if (strcmp (info->full_name, full_name) == 0 ||
- (is_inbox && g_ascii_strcasecmp (info->full_name, full_name) == 0))
- return info;
- camel_store_summary_info_unref ((CamelStoreSummary *) s, (CamelStoreInfo *) info);
+ CamelStoreInfo *match = NULL;
+ GPtrArray *array;
+ gboolean find_inbox;
+ guint ii;
+
+ find_inbox = camel_imapx_mailbox_is_inbox (full_name);
+
+ array = camel_store_summary_array (CAMEL_STORE_SUMMARY (s));
+
+ for (ii = 0; ii < array->len; ii++) {
+ CamelIMAPXStoreInfo *info;
+ gboolean is_inbox;
+
+ info = g_ptr_array_index (array, ii);
+ is_inbox = camel_imapx_mailbox_is_inbox (info->full_name);
+
+ if (find_inbox && is_inbox) {
+ match = camel_store_summary_info_ref (
+ CAMEL_STORE_SUMMARY (s),
+ (CamelStoreInfo *) info);
+ break;
+ }
+
+ if (g_str_equal (info->full_name, full_name)) {
+ match = camel_store_summary_info_ref (
+ CAMEL_STORE_SUMMARY (s),
+ (CamelStoreInfo *) info);
+ break;
}
}
- return NULL;
+ camel_store_summary_array_free (CAMEL_STORE_SUMMARY (s), array);
+
+ return (CamelIMAPXStoreInfo *) match;
}
gchar *
diff --git a/camel/camel-imapx-store.c b/camel/camel-imapx-store.c
index c413249..140650d 100644
--- a/camel/camel-imapx-store.c
+++ b/camel/camel-imapx-store.c
@@ -503,15 +503,15 @@ get_folder_offline (CamelStore *store,
CamelFolder *new_folder = NULL;
CamelStoreInfo *si;
CamelService *service;
- CamelStoreSummary *summary;
+ CamelStoreSummary *store_summary;
const gchar *user_cache_dir;
gboolean is_inbox;
service = CAMEL_SERVICE (store);
user_cache_dir = camel_service_get_user_cache_dir (service);
- summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
- si = camel_store_summary_path (summary, folder_name);
+ store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
+ si = camel_store_summary_path (store_summary, folder_name);
is_inbox = camel_imapx_mailbox_is_inbox (folder_name);
if (si == NULL && is_inbox)
@@ -539,7 +539,7 @@ get_folder_offline (CamelStore *store,
g_free (folder_dir);
g_free (base_dir);
- camel_store_summary_info_unref (summary, si);
+ camel_store_summary_info_unref (store_summary, si);
} else {
g_set_error (
error, CAMEL_STORE_ERROR,
@@ -853,45 +853,50 @@ rename_folder_info (CamelIMAPXStore *imapx_store,
const gchar *old_name,
const gchar *new_name)
{
- CamelStoreSummary *summary;
- gint i, count;
- CamelStoreInfo *si;
+ CamelStoreSummary *store_summary;
+ GPtrArray *array;
gint olen = strlen (old_name);
- const gchar *path;
- gchar *npath, *nfull;
+ guint ii;
- summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
+ store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
- count = camel_store_summary_count (summary);
- for (i = 0; i < count; i++) {
- si = camel_store_summary_index (summary, i);
- if (si == NULL)
- continue;
- path = camel_store_info_path (summary, si);
- if (strncmp (path, old_name, olen) == 0) {
- if (strlen (path) > olen)
- npath = g_strdup_printf ("%s/%s", new_name, path + olen + 1);
- else
- npath = g_strdup (new_name);
- nfull = camel_imapx_store_summary_path_to_full (
- imapx_store->summary, npath,
- imapx_store->dir_sep);
+ array = camel_store_summary_array (store_summary);
- camel_store_info_set_string (
- summary, si,
- CAMEL_STORE_INFO_PATH, npath);
- camel_store_info_set_string (
- summary, si,
- CAMEL_IMAPX_STORE_INFO_FULL_NAME, nfull);
+ for (ii = 0; ii < array->len; ii++) {
+ CamelStoreInfo *si;
+ const gchar *path;
+ gchar *new_path;
+ gchar *new_full;
- camel_store_summary_touch (summary);
+ si = g_ptr_array_index (array, ii);
+ path = camel_store_info_path (store_summary, si);
- g_free (nfull);
- g_free (npath);
- }
+ if (strncmp (path, old_name, olen) != 0)
+ continue;
- camel_store_summary_info_unref (summary, si);
+ if (strlen (path) > olen)
+ new_path = g_strdup_printf (
+ "%s/%s", new_name, path + olen + 1);
+ else
+ new_path = g_strdup (new_name);
+ new_full = camel_imapx_store_summary_path_to_full (
+ imapx_store->summary, new_path,
+ imapx_store->dir_sep);
+
+ camel_store_info_set_string (
+ store_summary, si,
+ CAMEL_STORE_INFO_PATH, new_path);
+ camel_store_info_set_string (
+ store_summary, si,
+ CAMEL_IMAPX_STORE_INFO_FULL_NAME, new_full);
+
+ camel_store_summary_touch (store_summary);
+
+ g_free (new_full);
+ g_free (new_path);
}
+
+ camel_store_summary_array_free (store_summary, array);
}
static void
@@ -937,13 +942,15 @@ get_folder_info_offline (CamelStore *store,
CamelIMAPXStore *imapx_store = CAMEL_IMAPX_STORE (store);
CamelService *service;
CamelSettings *settings;
+ CamelStoreSummary *store_summary;
gboolean include_inbox = FALSE;
CamelFolderInfo *fi;
GPtrArray *folders;
+ GPtrArray *array;
gchar *pattern, *name;
gboolean use_namespace;
gboolean use_subscriptions;
- gint i;
+ guint ii;
service = CAMEL_SERVICE (store);
@@ -999,21 +1006,23 @@ get_folder_info_offline (CamelStore *store,
* the moment. So let it do the right thing by bailing out if it's
* not a folder we're explicitly interested in. */
- for (i = 0; i < camel_store_summary_count ((CamelStoreSummary *) imapx_store->summary); i++) {
- CamelStoreInfo *si = camel_store_summary_index ((CamelStoreSummary *) imapx_store->summary,
i);
+ store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
+
+ array = camel_store_summary_array (store_summary);
+
+ for (ii = 0; ii < array->len; ii++) {
+ CamelStoreInfo *si;
const gchar *full_name;
CamelIMAPXStoreNamespace *ns;
- if (si == NULL)
- continue;
+ si = g_ptr_array_index (array, ii);
full_name = ((CamelIMAPXStoreInfo *) si)->full_name;
- if (!full_name || !*full_name) {
- camel_store_summary_info_unref ((CamelStoreSummary *) imapx_store->summary, si);
+ if (full_name == NULL || *full_name == '\0')
continue;
- }
- ns = camel_imapx_store_summary_namespace_find_full (imapx_store->summary, full_name);
+ ns = camel_imapx_store_summary_namespace_find_full (
+ imapx_store->summary, full_name);
/* Modify the checks to see match the namespaces from preferences */
if ((g_str_equal (name, full_name)
@@ -1024,7 +1033,7 @@ get_folder_info_offline (CamelStore *store,
|| (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED)
|| (flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIPTION_LIST) != 0)) {
- fi = imapx_build_folder_info (imapx_store, camel_store_info_path ((CamelStoreSummary
*) imapx_store->summary, si));
+ fi = imapx_build_folder_info (imapx_store, camel_store_info_path (store_summary, si));
fi->unread = si->unread;
fi->total = si->total;
if ((fi->flags & CAMEL_FOLDER_TYPE_MASK) != 0)
@@ -1045,8 +1054,10 @@ get_folder_info_offline (CamelStore *store,
fi->flags |= CAMEL_FOLDER_NOCHILDREN;
g_ptr_array_add (folders, fi);
}
- camel_store_summary_info_unref ((CamelStoreSummary *) imapx_store->summary, si);
}
+
+ camel_store_summary_array_free (store_summary, array);
+
g_free (pattern);
fi = camel_folder_info_build (folders, top, '/', TRUE);
@@ -1285,8 +1296,9 @@ sync_folders (CamelIMAPXStore *imapx_store,
CamelSettings *settings;
CamelStoreSummary *store_summary;
GHashTable *folders_from_server;
+ GPtrArray *array;
gboolean notify_all;
- gint ii, total;
+ guint ii;
store_summary = CAMEL_STORE_SUMMARY (imapx_store->summary);
@@ -1301,9 +1313,9 @@ sync_folders (CamelIMAPXStore *imapx_store,
CAMEL_IMAPX_SETTINGS (settings));
g_object_unref (settings);
- total = camel_store_summary_count (store_summary);
+ array = camel_store_summary_array (store_summary);
- for (ii = 0; ii < total; ii++) {
+ for (ii = 0; ii < array->len; ii++) {
CamelStoreInfo *si;
CamelFolderInfo *fi;
CamelIMAPXStoreNamespace *ns;
@@ -1311,13 +1323,11 @@ sync_folders (CamelIMAPXStore *imapx_store,
const gchar *si_path;
gboolean pattern_match;
- si = camel_store_summary_index (store_summary, ii);
- if (si == NULL)
- continue;
+ si = g_ptr_array_index (array, ii);
full_name = ((CamelIMAPXStoreInfo *) si)->full_name;
if (full_name == NULL || *full_name == '\0')
- goto endloop;
+ continue;
ns = camel_imapx_store_summary_namespace_find_full (
imapx_store->summary, full_name);
@@ -1326,7 +1336,7 @@ sync_folders (CamelIMAPXStore *imapx_store,
(pattern == NULL) || (*pattern == '\0') ||
imapx_match_pattern (ns, pattern, full_name);
if (!pattern_match)
- goto endloop;
+ continue;
si_path = camel_store_info_path (store_summary, si);
fi = g_hash_table_lookup (folders_from_server, si_path);
@@ -1362,15 +1372,11 @@ sync_folders (CamelIMAPXStore *imapx_store,
} else {
camel_store_summary_remove (store_summary, si);
}
-
- total--;
- ii--;
}
-
-endloop:
- camel_store_summary_info_unref (store_summary, si);
}
+ camel_store_summary_array_free (store_summary, array);
+
g_hash_table_destroy (folders_from_server);
return TRUE;
diff --git a/camel/providers/nntp/camel-nntp-store-summary.c b/camel/providers/nntp/camel-nntp-store-summary.c
index afb8a5d..cbf0548 100644
--- a/camel/providers/nntp/camel-nntp-store-summary.c
+++ b/camel/providers/nntp/camel-nntp-store-summary.c
@@ -108,20 +108,28 @@ CamelNNTPStoreInfo *
camel_nntp_store_summary_full_name (CamelNNTPStoreSummary *s,
const gchar *full_name)
{
- gint count, i;
- CamelNNTPStoreInfo *info;
+ CamelStoreInfo *match = NULL;
+ GPtrArray *array;
+ guint ii;
+
+ array = camel_store_summary_array (CAMEL_STORE_SUMMARY (s));
+
+ for (ii = 0; ii < array->len; ii++) {
+ CamelNNTPStoreInfo *info;
- count = camel_store_summary_count ((CamelStoreSummary *) s);
- for (i = 0; i < count; i++) {
- info = (CamelNNTPStoreInfo *) camel_store_summary_index ((CamelStoreSummary *) s, i);
- if (info) {
- if (strcmp (info->full_name, full_name) == 0)
- return info;
- camel_store_summary_info_unref ((CamelStoreSummary *) s, (CamelStoreInfo *) info);
+ info = g_ptr_array_index (array, ii);
+
+ if (g_str_equal (info->full_name, full_name)) {
+ match = camel_store_summary_info_ref (
+ CAMEL_STORE_SUMMARY (s),
+ (CamelStoreInfo *) info);
+ break;
}
}
- return NULL;
+ camel_store_summary_array_free (CAMEL_STORE_SUMMARY (s), array);
+
+ return (CamelNNTPStoreInfo *) match;
}
gchar *
diff --git a/camel/providers/nntp/camel-nntp-store.c b/camel/providers/nntp/camel-nntp-store.c
index e9689bf..395f7e6 100644
--- a/camel/providers/nntp/camel-nntp-store.c
+++ b/camel/providers/nntp/camel-nntp-store.c
@@ -736,7 +736,7 @@ nntp_folder_info_from_name (CamelNNTPStore *store,
}
/* handle list/newgroups response */
-static CamelNNTPStoreInfo *
+static CamelStoreInfo *
nntp_store_info_update (CamelNNTPStore *nntp_store,
gchar *line)
{
@@ -802,7 +802,7 @@ nntp_store_info_update (CamelNNTPStore *nntp_store,
g_clear_object (&nntp_store_summary);
- return si;
+ return (CamelStoreInfo *) si;
}
static CamelFolderInfo *
@@ -817,8 +817,9 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *nntp_store,
CamelService *service;
CamelSettings *settings;
CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL;
+ GPtrArray *array;
gboolean short_folder_names;
- guint ii, store_summary_count;
+ guint ii;
/* since we do not do a tree, any request that is not for root is sure to give no results */
if (top != NULL && top[0] != 0)
@@ -836,56 +837,60 @@ nntp_store_get_subscribed_folder_info (CamelNNTPStore *nntp_store,
nntp_store_summary = camel_nntp_store_ref_summary (nntp_store);
store_summary = CAMEL_STORE_SUMMARY (nntp_store_summary);
- store_summary_count = camel_store_summary_count (store_summary);
- for (ii = 0; ii < store_summary_count; ii++) {
+ array = camel_store_summary_array (store_summary);
+
+ for (ii = 0; ii < array->len; ii++) {
CamelStoreInfo *si;
- si = camel_store_summary_index (store_summary, ii);
- if (si == NULL)
+ si = g_ptr_array_index (array, ii);
+
+ if ((si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) == 0)
continue;
- if (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED) {
- /* slow mode? open and update the folder, always! this will implictly update
- * our storeinfo too; in a very round-about way */
- if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) {
- CamelNNTPFolder *folder;
- gchar *line;
-
- folder = (CamelNNTPFolder *)
- camel_store_get_folder_sync (
- (CamelStore *) nntp_store, si->path,
- 0, cancellable, NULL);
- if (folder) {
- CamelFolderChangeInfo *changes = NULL;
-
- if (camel_nntp_command (nntp_store, cancellable, NULL, folder, &line,
NULL) != -1) {
- if (camel_folder_change_info_changed (folder->changes)) {
- changes = folder->changes;
- folder->changes = camel_folder_change_info_new ();
- }
+ /* slow mode? open and update the folder, always! this will
+ * implictly update our storeinfo too; in a very round-about
+ * way */
+ if ((flags & CAMEL_STORE_FOLDER_INFO_FAST) == 0) {
+ CamelNNTPFolder *folder;
+ gchar *line;
+
+ folder = (CamelNNTPFolder *)
+ camel_store_get_folder_sync (
+ (CamelStore *) nntp_store, si->path,
+ 0, cancellable, NULL);
+ if (folder) {
+ CamelFolderChangeInfo *changes = NULL;
+
+ if (camel_nntp_command (nntp_store, cancellable, NULL, folder, &line, NULL)
!= -1) {
+ if (camel_folder_change_info_changed (folder->changes)) {
+ changes = folder->changes;
+ folder->changes = camel_folder_change_info_new ();
}
- if (changes) {
- camel_folder_changed (CAMEL_FOLDER (folder), changes);
- camel_folder_change_info_free (changes);
- }
- g_object_unref (folder);
}
+ if (changes) {
+ camel_folder_changed (CAMEL_FOLDER (folder), changes);
+ camel_folder_change_info_free (changes);
+ }
+ g_object_unref (folder);
}
- fi = nntp_folder_info_from_store_info (nntp_store, short_folder_names, si);
- fi->flags |=
- CAMEL_FOLDER_NOINFERIORS |
- CAMEL_FOLDER_NOCHILDREN |
- CAMEL_FOLDER_SYSTEM;
- if (last)
- last->next = fi;
- else
- first = fi;
- last = fi;
}
- camel_store_summary_info_unref (store_summary, si);
+
+ fi = nntp_folder_info_from_store_info (
+ nntp_store, short_folder_names, si);
+ fi->flags |=
+ CAMEL_FOLDER_NOINFERIORS |
+ CAMEL_FOLDER_NOCHILDREN |
+ CAMEL_FOLDER_SYSTEM;
+ if (last)
+ last->next = fi;
+ else
+ first = fi;
+ last = fi;
}
+ camel_store_summary_array_free (store_summary, array);
+
g_clear_object (&nntp_store_summary);
return first;
@@ -983,6 +988,7 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *nntp_store,
CamelSettings *settings;
CamelFolderInfo *first = NULL, *last = NULL, *fi = NULL;
GHashTable *known; /* folder name to folder info */
+ GPtrArray *array;
gboolean folder_hierarchy_relative;
gchar *tmpname;
gchar *top = g_strconcat (orig_top ? orig_top:"", ".", NULL);
@@ -991,7 +997,7 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *nntp_store,
gint root_or_flag;
gint recursive_flag;
gint is_folder_list;
- guint ii, store_summary_count;
+ guint ii;
subscribed_or_flag =
(flags & CAMEL_STORE_FOLDER_INFO_SUBSCRIBED) ? 0 : 1;
@@ -1017,14 +1023,13 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *nntp_store,
known = g_hash_table_new (g_str_hash, g_str_equal);
store_summary = CAMEL_STORE_SUMMARY (nntp_store_summary);
- store_summary_count = camel_store_summary_count (store_summary);
- for (ii = 0; ii < store_summary_count; ii++) {
+ array = camel_store_summary_array (store_summary);
+
+ for (ii = 0; ii < array->len; ii++) {
CamelStoreInfo *si;
- si = camel_store_summary_index (store_summary, ii);
- if (si == NULL)
- continue;
+ si = g_ptr_array_index (array, ii);
if ((subscribed_or_flag || (si->flags & CAMEL_STORE_INFO_FOLDER_SUBSCRIBED))
&& (root_or_flag || strncmp (si->path, top, toplen) == 0)) {
@@ -1084,13 +1089,12 @@ nntp_store_get_cached_folder_info (CamelNNTPStore *nntp_store,
}
} else if (subscribed_or_flag && first) {
/* we have already added subitems, but this item is no longer a subitem */
- camel_store_summary_info_unref (store_summary, si);
break;
}
-
- camel_store_summary_info_unref (store_summary, si);
}
+ camel_store_summary_array_free (store_summary, array);
+
g_hash_table_destroy (known);
g_free (top);
@@ -1163,7 +1167,6 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
{
CamelNNTPStream *nntp_stream = NULL;
CamelNNTPStoreSummary *nntp_store_summary;
- CamelNNTPStoreInfo *si;
guint len;
guchar *line;
gint ret = -1;
@@ -1201,8 +1204,11 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
while ((ret = camel_nntp_stream_line (nntp_stream, &line, &len, cancellable, error))
0)
nntp_store_info_update (nntp_store, (gchar *) line);
} else {
+ CamelStoreSummary *store_summary;
+ CamelStoreInfo *si;
+ GPtrArray *array;
GHashTable *all;
- gint i;
+ guint ii;
do_complete_list:
/* seems we do need a complete list */
@@ -1221,14 +1227,23 @@ nntp_store_get_folder_info_all (CamelNNTPStore *nntp_store,
}
all = g_hash_table_new (g_str_hash, g_str_equal);
- for (i = 0; (si = (CamelNNTPStoreInfo *) camel_store_summary_index
(CAMEL_STORE_SUMMARY (nntp_store_summary), i)); i++)
- g_hash_table_insert (all, si->info.path, si);
+
+ store_summary = CAMEL_STORE_SUMMARY (nntp_store_summary);
+ array = camel_store_summary_array (store_summary);
+
+ for (ii = 0; ii < array->len; ii++) {
+ si = g_ptr_array_index (array, ii);
+ camel_store_summary_info_ref (store_summary, si);
+ g_hash_table_insert (all, si->path, si);
+ }
+
+ camel_store_summary_array_free (store_summary, array);
nntp_stream = camel_nntp_store_ref_stream (nntp_store);
while ((ret = camel_nntp_stream_line (nntp_stream, &line, &len, cancellable, error))
0) {
si = nntp_store_info_update (nntp_store, (gchar *) line);
- g_hash_table_remove (all, si->info.path);
+ g_hash_table_remove (all, si->path);
}
g_hash_table_foreach (
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]