]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
locking fixes
authorTimo Sirainen <tss@iki.fi>
Mon, 14 Jun 2004 05:48:23 +0000 (08:48 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 14 Jun 2004 05:48:23 +0000 (08:48 +0300)
--HG--
branch : HEAD

src/lib-storage/index/maildir/maildir-sync.c
src/lib-storage/index/maildir/maildir-uidlist.c
src/lib-storage/index/maildir/maildir-uidlist.h

index 8f60cdb1e3f83e704cb4d27f67f8c25a5cb7b934..b71a2022db2564ac58e760d93d3e5568a4dd07c7 100644 (file)
@@ -834,18 +834,18 @@ static int maildir_sync_context(struct maildir_sync_context *ctx)
        if (!new_changed && !cur_changed)
                return 0;
 
-       ctx->partial = !cur_changed;
-       ctx->uidlist_sync_ctx =
-               maildir_uidlist_sync_init(ctx->ibox->uidlist, ctx->partial);
-
        /* we have to lock uidlist immediately, otherwise there's race
           conditions with other processes who might write older maildir
           file list into uidlist.
 
           alternative would be to lock it when new files are found, but
           the directory scans _must_ be restarted then */
-       if (maildir_uidlist_try_lock(ctx->ibox->uidlist) < 0)
-               return -1;
+       if ((ret = maildir_uidlist_try_lock(ctx->ibox->uidlist)) <= 0)
+               return ret;
+
+       ctx->partial = !cur_changed;
+       ctx->uidlist_sync_ctx =
+               maildir_uidlist_sync_init(ctx->ibox->uidlist, ctx->partial);
 
        if (maildir_scan_dir(ctx, TRUE) < 0)
                return -1;
@@ -855,10 +855,9 @@ static int maildir_sync_context(struct maildir_sync_context *ctx)
        }
 
        /* finish uidlist syncing, but keep it still locked */
-       if (maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx)) {
-               if (maildir_sync_index(ctx) < 0)
-                       return -1;
-       }
+       maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);
+       if (maildir_sync_index(ctx) < 0)
+               return -1;
 
        ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx);
         ctx->uidlist_sync_ctx = NULL;
@@ -878,6 +877,7 @@ static int maildir_sync_context_readonly(struct maildir_sync_context *ctx)
        if (maildir_scan_dir(ctx, FALSE) < 0)
                return -1;
 
+       maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);
        ret = maildir_uidlist_sync_deinit(ctx->uidlist_sync_ctx);
         ctx->uidlist_sync_ctx = NULL;
 
index f7b9c0145f9a6b5f63b89c9e47063fef71acbfe5..23605219fd7eabcdfaad2809fa163353780b759c 100644 (file)
@@ -58,8 +58,6 @@ struct maildir_uidlist_sync_ctx {
        unsigned int new_files_count;
 
        unsigned int partial:1;
-       unsigned int synced:1;
-       unsigned int locked:1;
        unsigned int finished:1;
        unsigned int failed:1;
 };
@@ -592,42 +590,6 @@ maildir_uidlist_sync_init(struct maildir_uidlist *uidlist, int partial)
        return ctx;
 }
 
-static int maildir_uidlist_sync_uidlist(struct maildir_uidlist_sync_ctx *ctx)
-{
-       int ret;
-
-       i_assert(!ctx->synced);
-
-       if (UIDLIST_IS_LOCKED(ctx->uidlist)) {
-               ctx->synced = TRUE;
-               return 1;
-       }
-
-       if (!ctx->uidlist->initial_read) {
-               /* first time reading the uidlist,
-                  no locking yet */
-               if (maildir_uidlist_update(ctx->uidlist) < 0) {
-                       ctx->failed = TRUE;
-                       return -1;
-               }
-               return 0;
-       }
-
-       /* lock and update uidlist to see if it's just been added */
-       ret = maildir_uidlist_try_lock(ctx->uidlist);
-       if (ret <= 0) {
-               if (ret == 0) {
-                       ctx->locked = TRUE;
-                       return -1;
-               }
-               ctx->failed = TRUE;
-               return -1;
-       }
-
-       ctx->synced = TRUE;
-       return 1;
-}
-
 static int
 maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
                                  const char *filename,
@@ -638,7 +600,7 @@ maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
 
        /* we'll update uidlist directly */
        rec = hash_lookup(uidlist->files, filename);
-       i_assert(rec != NULL || ctx->synced);
+       i_assert(rec != NULL || UIDLIST_IS_LOCKED(uidlist));
 
        if (rec == NULL) {
                if (ctx->new_files_count == 0) {
@@ -673,19 +635,19 @@ maildir_uidlist_sync_next_partial(struct maildir_uidlist_sync_ctx *ctx,
 int maildir_uidlist_sync_next_pre(struct maildir_uidlist_sync_ctx *ctx,
                                  const char *filename)
 {
-       int ret;
-
-       if (!ctx->synced &&
+       if (!UIDLIST_IS_LOCKED(ctx->uidlist) &&
            hash_lookup(ctx->uidlist->files, filename) == NULL &&
            (ctx->partial || hash_lookup(ctx->files, filename) == NULL)) {
-               if (ctx->locked)
-                       return 0;
-
-               ret = maildir_uidlist_sync_uidlist(ctx);
-               if (ret < 0)
-                       return ctx->locked ? 0 : -1;
-               if (ret == 0)
+               if (!ctx->uidlist->initial_read) {
+                       /* first time reading the uidlist */
+                       if (maildir_uidlist_update(ctx->uidlist) < 0) {
+                               ctx->failed = TRUE;
+                               return -1;
+                       }
                        return maildir_uidlist_sync_next_pre(ctx, filename);
+               }
+
+               return 0;
        }
 
        return 1;
@@ -716,7 +678,7 @@ int maildir_uidlist_sync_next(struct maildir_uidlist_sync_ctx *ctx,
                                MAILDIR_UIDLIST_REC_FLAG_MOVED);
        } else {
                old_rec = hash_lookup(uidlist->files, filename);
-               i_assert(old_rec != NULL || ctx->synced);
+               i_assert(old_rec != NULL || UIDLIST_IS_LOCKED(uidlist));
 
                rec = p_new(ctx->record_pool, struct maildir_uidlist_rec, 1);
 
@@ -825,10 +787,10 @@ static void maildir_uidlist_swap(struct maildir_uidlist_sync_ctx *ctx)
        }
 }
 
-int maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx)
+void maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx)
 {
        if (!ctx->partial) {
-               if (!ctx->failed && !ctx->locked)
+               if (!ctx->failed)
                        maildir_uidlist_swap(ctx);
        } else {
                if (ctx->new_files_count != 0) {
@@ -839,7 +801,6 @@ int maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx)
 
        ctx->finished = TRUE;
        ctx->uidlist->initial_sync = TRUE;
-       return !ctx->locked;
 }
 
 int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx *ctx)
@@ -849,7 +810,7 @@ int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx *ctx)
        if (!ctx->finished)
                maildir_uidlist_sync_finish(ctx);
 
-       if (ctx->new_files_count != 0 && !ctx->failed && !ctx->locked) {
+       if (ctx->new_files_count != 0 && !ctx->failed) {
                t_push();
                ret = maildir_uidlist_rewrite(ctx->uidlist);
                t_pop();
index 63a0fa0be0696c9973c6aa9c3bbd3df711d7dbc9..191383493dd363556775b16af37f17dbf5d210a6 100644 (file)
@@ -44,8 +44,7 @@ int maildir_uidlist_sync_next_pre(struct maildir_uidlist_sync_ctx *ctx,
 int maildir_uidlist_sync_next(struct maildir_uidlist_sync_ctx *ctx,
                              const char *filename,
                              enum maildir_uidlist_rec_flag flags);
-/* Returns 1 = ok, 0 = uidlist is locked, don't try syncing any further */
-int maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx);
+void maildir_uidlist_sync_finish(struct maildir_uidlist_sync_ctx *ctx);
 int maildir_uidlist_sync_deinit(struct maildir_uidlist_sync_ctx *ctx);
 
 void maildir_uidlist_add_flags(struct maildir_uidlist *uidlist,