[evolution-data-server/gnome-3-20] [IMAPx] Add thread-safety locking around server's private 'changes' property
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/gnome-3-20] [IMAPx] Add thread-safety locking around server's private 'changes' property
- Date: Tue, 5 Apr 2016 11:53:10 +0000 (UTC)
commit 9dc43f93b28ef7b3e0b3b013c0440345a94c4c15
Author: Milan Crha <mcrha redhat com>
Date: Tue Apr 5 13:51:22 2016 +0200
[IMAPx] Add thread-safety locking around server's private 'changes' property
The 'changes' could be accessed from multiple threads, thus add
thread safety to it by using a mutex when accessing it.
camel/providers/imapx/camel-imapx-server.c | 87 +++++++++++++++++++++++-----
1 files changed, 73 insertions(+), 14 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-server.c b/camel/providers/imapx/camel-imapx-server.c
index b491407..0881c06 100644
--- a/camel/providers/imapx/camel-imapx-server.c
+++ b/camel/providers/imapx/camel-imapx-server.c
@@ -255,6 +255,8 @@ struct _CamelIMAPXServerPrivate {
GMutex select_lock;
GWeakRef select_mailbox;
GWeakRef select_pending;
+
+ GMutex changes_lock;
CamelFolderChangeInfo *changes;
/* Data items to request in STATUS commands:
@@ -760,14 +762,26 @@ imapx_expunge_uid_from_summary (CamelIMAPXServer *is,
g_return_if_fail (is->priv->changes != NULL);
camel_folder_summary_remove_uid (folder->summary, uid);
+
+ g_mutex_lock (&is->priv->changes_lock);
+
camel_folder_change_info_remove_uid (is->priv->changes, uid);
if (camel_imapx_server_is_in_idle (is)) {
+ CamelFolderChangeInfo *changes;
+
+ changes = is->priv->changes;
+ is->priv->changes = camel_folder_change_info_new ();
+
+ g_mutex_unlock (&is->priv->changes_lock);
+
camel_folder_summary_save_to_db (folder->summary, NULL);
imapx_update_store_summary (folder);
- camel_folder_changed (folder, is->priv->changes);
+ camel_folder_changed (folder, changes);
- camel_folder_change_info_clear (is->priv->changes);
+ camel_folder_change_info_free (changes);
+ } else {
+ g_mutex_unlock (&is->priv->changes_lock);
}
g_object_unref (folder);
@@ -938,6 +952,8 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
g_return_val_if_fail (is->priv->changes != NULL, FALSE);
+ g_mutex_lock (&is->priv->changes_lock);
+
for (ii = 0; ii < uids->len; ii++) {
guint32 uid;
gchar *str;
@@ -951,22 +967,38 @@ imapx_untagged_vanished (CamelIMAPXServer *is,
camel_folder_change_info_remove_uid (is->priv->changes, str);
}
+ g_mutex_unlock (&is->priv->changes_lock);
+
uid_list = g_list_reverse (uid_list);
camel_folder_summary_remove_uids (folder->summary, uid_list);
- COMMAND_LOCK (is);
-
/* If the response is truly unsolicited (e.g. via NOTIFY)
* then go ahead and emit the change notification now. */
- if (!is->priv->current_command && is->priv->changes->uid_removed &&
- is->priv->changes->uid_removed->len >= 100) {
- camel_folder_summary_save_to_db (folder->summary, NULL);
- imapx_update_store_summary (folder);
- camel_folder_changed (folder, is->priv->changes);
- camel_folder_change_info_clear (is->priv->changes);
- }
+ COMMAND_LOCK (is);
+ if (!is->priv->current_command) {
+ COMMAND_UNLOCK (is);
- COMMAND_UNLOCK (is);
+ g_mutex_lock (&is->priv->changes_lock);
+ if (is->priv->changes->uid_removed &&
+ is->priv->changes->uid_removed->len >= 100) {
+ CamelFolderChangeInfo *changes;
+
+ changes = is->priv->changes;
+ is->priv->changes = camel_folder_change_info_new ();
+
+ g_mutex_unlock (&is->priv->changes_lock);
+
+ camel_folder_summary_save_to_db (folder->summary, NULL);
+ imapx_update_store_summary (folder);
+
+ camel_folder_changed (folder, changes);
+ camel_folder_change_info_free (changes);
+ } else {
+ g_mutex_unlock (&is->priv->changes_lock);
+ }
+ } else {
+ COMMAND_UNLOCK (is);
+ }
g_list_free_full (uid_list, (GDestroyNotify) g_free);
g_array_free (uids, TRUE);
@@ -1232,15 +1264,22 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
if (changed) {
g_return_val_if_fail (is->priv->changes != NULL, FALSE);
+ g_mutex_lock (&is->priv->changes_lock);
camel_folder_change_info_change_uid (is->priv->changes, uid);
+ g_mutex_unlock (&is->priv->changes_lock);
}
g_free (uid);
if (changed && camel_imapx_server_is_in_idle (is)) {
camel_folder_summary_save_to_db (select_folder->summary, NULL);
imapx_update_store_summary (select_folder);
+
+ g_mutex_lock (&is->priv->changes_lock);
+
camel_folder_changed (select_folder, is->priv->changes);
camel_folder_change_info_clear (is->priv->changes);
+
+ g_mutex_unlock (&is->priv->changes_lock);
}
if (mi)
@@ -1347,9 +1386,13 @@ imapx_untagged_fetch (CamelIMAPXServer *is,
imapx_set_message_info_flags_for_new_message (mi, server_flags,
server_user_flags, FALSE, NULL, camel_imapx_mailbox_get_permanentflags (mailbox));
camel_folder_summary_add (folder->summary, mi);
+ g_mutex_lock (&is->priv->changes_lock);
+
camel_folder_change_info_add_uid (is->priv->changes, mi->uid);
camel_folder_change_info_recent_uid (is->priv->changes, mi->uid);
+ g_mutex_unlock (&is->priv->changes_lock);
+
if (messages > 0) {
gint cnt = (camel_folder_summary_count (folder->summary) * 100) /
messages;
@@ -2261,9 +2304,17 @@ imapx_completion (CamelIMAPXServer *is,
c (is->priv->tagprefix, "Got completion response for command %05u '%s'\n", ic->tag,
camel_imapx_job_get_kind_name (ic->job_kind));
+ g_mutex_lock (&is->priv->changes_lock);
+
if (camel_folder_change_info_changed (is->priv->changes)) {
CamelFolder *folder = NULL;
CamelIMAPXMailbox *mailbox;
+ CamelFolderChangeInfo *changes;
+
+ changes = is->priv->changes;
+ is->priv->changes = camel_folder_change_info_new ();
+
+ g_mutex_unlock (&is->priv->changes_lock);
mailbox = camel_imapx_server_ref_selected (is);
@@ -2276,13 +2327,15 @@ imapx_completion (CamelIMAPXServer *is,
camel_folder_summary_save_to_db (folder->summary, NULL);
imapx_update_store_summary (folder);
- camel_folder_changed (folder, is->priv->changes);
+ camel_folder_changed (folder, changes);
}
- camel_folder_change_info_clear (is->priv->changes);
+ camel_folder_change_info_free (changes);
g_clear_object (&folder);
g_clear_object (&mailbox);
+ } else {
+ g_mutex_unlock (&is->priv->changes_lock);
}
if (g_list_next (ic->current_part) != NULL) {
@@ -3290,6 +3343,7 @@ imapx_server_finalize (GObject *object)
g_mutex_clear (&is->priv->stream_lock);
g_mutex_clear (&is->priv->select_lock);
+ g_mutex_clear (&is->priv->changes_lock);
camel_folder_change_info_free (is->priv->changes);
imapx_free_status (is->priv->copyuid_status);
@@ -3382,6 +3436,7 @@ camel_imapx_server_init (CamelIMAPXServer *is)
g_mutex_init (&is->priv->stream_lock);
g_mutex_init (&is->priv->inactivity_timeout_lock);
g_mutex_init (&is->priv->select_lock);
+ g_mutex_init (&is->priv->changes_lock);
g_mutex_init (&is->priv->search_results_lock);
g_mutex_init (&is->priv->known_alerts_lock);
@@ -4593,7 +4648,9 @@ camel_imapx_server_append_message_sync (CamelIMAPXServer *is,
camel_folder_summary_add (folder->summary, mi);
+ g_mutex_lock (&is->priv->changes_lock);
camel_folder_change_info_add_uid (is->priv->changes, mi->uid);
+ g_mutex_unlock (&is->priv->changes_lock);
mi = NULL;
@@ -4736,7 +4793,9 @@ imapx_server_process_fetch_changes_infos (CamelIMAPXServer *is,
nfo->server_user_flags,
camel_imapx_mailbox_get_permanentflags (mailbox),
folder, FALSE)) {
+ g_mutex_lock (&is->priv->changes_lock);
camel_folder_change_info_change_uid (is->priv->changes, camel_message_info_uid
(minfo));
+ g_mutex_unlock (&is->priv->changes_lock);
}
camel_message_info_unref (minfo);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]