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;
}
/* 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;
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;
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;
};
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,
/* 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) {
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;
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);
}
}
-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) {
ctx->finished = TRUE;
ctx->uidlist->initial_sync = TRUE;
- return !ctx->locked;
}
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();
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,