]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Mail cache: lock_method=dotlock could have caused a process to deadlock with itself.
authorTimo Sirainen <tss@iki.fi>
Thu, 11 Sep 2008 13:52:47 +0000 (16:52 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 11 Sep 2008 13:52:47 +0000 (16:52 +0300)
--HG--
branch : HEAD

src/lib-index/mail-cache-compress.c
src/lib-index/mail-cache-private.h
src/lib-index/mail-cache.c

index d8879649fd85f2da42cce31f6703fa46a7b2171f..e64209f5ae4efd3549dfeaa0624e2f2b3983b064 100644 (file)
@@ -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)
index 4825e8f1f36286438b8d4f4734b70eb735d0a78a..57e3e48016075bd0dccc0d43f333392e6a20e967 100644 (file)
@@ -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 {
index 36c5a7f44f808d0a2d7ee39993730a509aa943a0..b2df74da28361aa3af8d4b1b9a8fb3abceb92b88 100644 (file)
@@ -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);