Mercurial > dovecot > core-2.2
changeset 627:49893535ce92 HEAD
Avoid rebuilding tree twice if two processes notice it's broken at the same
time.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 20 Nov 2002 18:15:57 +0200 |
parents | 5ce5aafe28d9 |
children | e4aba04143ad |
files | src/lib-index/mail-tree.c |
diffstat | 1 files changed, 40 insertions(+), 23 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-tree.c Wed Nov 20 18:06:24 2002 +0200 +++ b/src/lib-index/mail-tree.c Wed Nov 20 18:15:57 2002 +0200 @@ -201,6 +201,32 @@ return TRUE; } +static int mail_tree_open_init(MailTree *tree) +{ + if (!mmap_update(tree)) + return FALSE; + + if (tree->mmap_full_length == 0) { + /* just created it */ + return FALSE; + } + + if (!mmap_verify(tree)) { + /* broken header */ + return FALSE; + } + + if (tree->header->indexid != tree->index->indexid) { + index_set_error(tree->index, + "IndexID mismatch for binary tree file %s", + tree->filepath); + + return FALSE; + } + + return TRUE; +} + int mail_tree_open_or_create(MailIndex *index) { MailTree *tree; @@ -209,32 +235,23 @@ if (tree == NULL) return FALSE; - do { - if (!mmap_update(tree)) - break; - - if (tree->mmap_full_length == 0) { - /* just created it */ - if (!mail_tree_rebuild(tree)) - break; - } else if (!mmap_verify(tree)) { - /* broken header */ - if (!mail_tree_rebuild(tree)) - break; - } else if (tree->header->indexid != index->indexid) { - index_set_error(tree->index, - "IndexID mismatch for binary tree file %s", - tree->filepath); - - if (!mail_tree_rebuild(tree)) - break; + if (!mail_tree_open_init(tree)) { + /* lock and check again, just to avoid rebuilding it twice + if two processes notice the error at the same time */ + if (!tree->index->set_lock(tree->index, MAIL_LOCK_EXCLUSIVE)) { + mail_tree_free(tree); + return FALSE; } - return TRUE; - } while (0); + if (!mail_tree_open_init(tree)) { + if (!mail_tree_rebuild(tree)) { + mail_tree_free(tree); + return FALSE; + } + } + } - mail_tree_free(tree); - return FALSE; + return TRUE; } static void mail_tree_close(MailTree *tree)