From 7cf50b7d90f5cf681da0e6bd8a52a4d8528a39da Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 28 Sep 2001 02:37:53 +0000 Subject: 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 --- camel/ChangeLog | 14 ++++++++++++++ camel/providers/imap/camel-imap-folder.c | 17 +++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 8c77bf23d4..837aee044e 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,17 @@ +2001-09-27 Dan Winship + + * 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 + 2001-09-27 * camel-service.c (camel_service_connect): Dont re-register the 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; -- cgit v1.2.3