From: Timo Sirainen Date: Thu, 11 Sep 2008 13:52:47 +0000 (+0300) Subject: Mail cache: lock_method=dotlock could have caused a process to deadlock with itself. X-Git-Tag: 1.2.alpha2~61 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5724e7103eed12fe36b55a7b5a8653284a2184b9;p=thirdparty%2Fdovecot%2Fcore.git Mail cache: lock_method=dotlock could have caused a process to deadlock with itself. --HG-- branch : HEAD --- diff --git a/src/lib-index/mail-cache-compress.c b/src/lib-index/mail-cache-compress.c index d8879649fd..e64209f5ae 100644 --- a/src/lib-index/mail-cache-compress.c +++ b/src/lib-index/mail-cache-compress.c @@ -433,6 +433,7 @@ static int mail_cache_compress_locked(struct mail_cache *cache, cache->fd = fd; cache->st_ino = st.st_ino; cache->st_dev = st.st_dev; + cache->field_header_write_pending = FALSE; if (cache->file_cache != NULL) file_cache_set_fd(cache->file_cache, cache->fd); @@ -452,6 +453,8 @@ int mail_cache_compress(struct mail_cache *cache, bool unlock = FALSE; int ret; + i_assert(!cache->compressing); + if (MAIL_INDEX_IS_IN_MEMORY(cache->index) || cache->index->readonly) return 0; @@ -463,26 +466,27 @@ int mail_cache_compress(struct mail_cache *cache, cache->filepath, cache->fd, FALSE); } - return mail_cache_compress_locked(cache, trans, &unlock); - } - - switch (mail_cache_lock(cache, FALSE)) { - case -1: - return -1; - case 0: - /* couldn't lock, either it's broken or doesn't exist. - just start creating it. */ - return mail_cache_compress_locked(cache, trans, &unlock); - default: - /* locking succeeded. */ - unlock = TRUE; - ret = mail_cache_compress_locked(cache, trans, &unlock); - if (unlock) { - if (mail_cache_unlock(cache) < 0) - ret = -1; + } else { + switch (mail_cache_lock(cache, FALSE)) { + case -1: + return -1; + case 0: + /* couldn't lock, either it's broken or doesn't exist. + just start creating it. */ + break; + default: + /* locking succeeded. */ + unlock = TRUE; } - return ret; } + cache->compressing = TRUE; + ret = mail_cache_compress_locked(cache, trans, &unlock); + cache->compressing = FALSE; + if (unlock) { + if (mail_cache_unlock(cache) < 0) + ret = -1; + } + return ret; } bool mail_cache_need_compress(struct mail_cache *cache) diff --git a/src/lib-index/mail-cache-private.h b/src/lib-index/mail-cache-private.h index 4825e8f1f3..57e3e48016 100644 --- a/src/lib-index/mail-cache-private.h +++ b/src/lib-index/mail-cache-private.h @@ -173,6 +173,7 @@ struct mail_cache { unsigned int locked:1; unsigned int hdr_modified:1; unsigned int field_header_write_pending:1; + unsigned int compressing:1; }; struct mail_cache_loop_track { diff --git a/src/lib-index/mail-cache.c b/src/lib-index/mail-cache.c index 36c5a7f44f..b2df74da28 100644 --- a/src/lib-index/mail-cache.c +++ b/src/lib-index/mail-cache.c @@ -667,7 +667,8 @@ void mail_cache_view_close(struct mail_cache_view *view) { i_assert(view->trans_view == NULL); - if (view->cache->field_header_write_pending) + if (view->cache->field_header_write_pending && + !view->cache->compressing) (void)mail_cache_header_fields_update(view->cache); buffer_free(&view->cached_exists_buf);