aboutsummaryrefslogtreecommitdiffstats
path: root/camel/providers
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2001-09-28 10:37:53 +0800
committerDan Winship <danw@src.gnome.org>2001-09-28 10:37:53 +0800
commit7cf50b7d90f5cf681da0e6bd8a52a4d8528a39da (patch)
tree042f73b250a56c38cc5c34e0dd6892d884085808 /camel/providers
parent220fba647b57d5d671929dafad86cc7e226bd26f (diff)
downloadgsoc2013-evolution-7cf50b7d90f5cf681da0e6bd8a52a4d8528a39da.tar.gz
gsoc2013-evolution-7cf50b7d90f5cf681da0e6bd8a52a4d8528a39da.tar.zst
gsoc2013-evolution-7cf50b7d90f5cf681da0e6bd8a52a4d8528a39da.zip
Grab the store's command_lock before grabbing the folder's cache_lock to
* providers/imap/camel-imap-folder.c (camel_imap_folder_fetch_data): Grab the store's command_lock before grabbing the folder's cache_lock to prevent deadlock if another thread is processing an EXPUNGE response. * providers/imap/camel-imap-folder.c (imap_expunge_uids_resyncing): Fix a compiler warning that might point out a real bug... * providers/imap/camel-imap-folder.c (get_content): and one that doesn't svn path=/trunk/; revision=13209
Diffstat (limited to 'camel/providers')
-rw-r--r--camel/providers/imap/camel-imap-folder.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c
index be0be6575d..6b4b65c4b7 100644
--- a/camel/providers/imap/camel-imap-folder.c
+++ b/camel/providers/imap/camel-imap-folder.c
@@ -793,7 +793,7 @@ imap_expunge_uids_resyncing (CamelFolder *folder, GPtrArray *uids, CamelExceptio
for (ei = ki = 0; ei < uids->len; ei++) {
euid = strtoul (uids->pdata[ei], NULL, 10);
- for (; ki < keep_uids->len; ki++) {
+ for (kuid = 0; ki < keep_uids->len; ki++) {
kuid = strtoul (keep_uids->pdata[ki], NULL, 10);
if (kuid >= euid)
@@ -1329,7 +1329,7 @@ get_content (CamelImapFolder *imap_folder, const char *uid,
const char *part_spec, CamelMimePart *part,
CamelMessageContentInfo *ci, CamelException *ex)
{
- CamelDataWrapper *content;
+ CamelDataWrapper *content = NULL;
CamelStream *stream;
char *child_spec;
@@ -1876,12 +1876,21 @@ camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
char *found_uid;
int i;
+ /* EXPUNGE responses have to modify the cache, which means
+ * they have to grab the cache_lock while holding the
+ * command_lock. So we grab the command_lock now, in case
+ * we're going to need it below, since we can't grab it
+ * after the cache_lock.
+ */
+ CAMEL_IMAP_STORE_LOCK (store, command_lock);
+
CAMEL_IMAP_FOLDER_LOCK (imap_folder, cache_lock);
stream = camel_imap_message_cache_get (imap_folder->cache, uid, section_text);
if (!stream && (!strcmp (section_text, "HEADER") || !strcmp (section_text, "0")))
stream = camel_imap_message_cache_get (imap_folder->cache, uid, "");
if (stream || cache_only) {
CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
+ CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
return stream;
}
@@ -1889,6 +1898,7 @@ camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
camel_exception_set (ex, CAMEL_EXCEPTION_SERVICE_UNAVAILABLE,
_("This message is not currently available"));
CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
+ CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
return NULL;
}
@@ -1901,6 +1911,9 @@ camel_imap_folder_fetch_data (CamelImapFolder *imap_folder, const char *uid,
"UID FETCH %s BODY.PEEK[%s]",
uid, section_text);
}
+ /* We won't need the command_lock again after this. */
+ CAMEL_IMAP_STORE_UNLOCK (store, command_lock);
+
if (!response) {
CAMEL_IMAP_FOLDER_UNLOCK (imap_folder, cache_lock);
return NULL;