Browse Source

don't expunge until all flag propagation is complete

so far, we ensured that propagation _into_ a store completes before
expunging it, but not that propagation _from_ it completes. this way we
could end up expunging the source messages before the changes reached
the target, which could mess up resuming after an interruption.
wip/maildir-path-under-inbox
Oswald Buddenhagen 3 years ago
parent
commit
13764a94b9
  1. 8
      src/sync.c

8
src/sync.c

@ -40,7 +40,7 @@ static int check_cancel( sync_vars_t *svars );
new(F), new(N), flags(F), flags(N): load(F) & load(N) new(F), new(N), flags(F), flags(N): load(F) & load(N)
find_new(x): new(x) find_new(x): new(x)
trash(x): flags(x) trash(x): flags(x)
close(x): trash(x) & find_new(x) & new(!x) // with expunge close(x): trash(x) & flags(!x) & find_new(x) & new(!x) // with expunge
cleanup: close(F) & close(N) cleanup: close(F) & close(N)
*/ */
@ -1557,6 +1557,10 @@ msgs_flags_set( sync_vars_t *svars, int t )
sync_ref( svars ); sync_ref( svars );
sync_close( svars, t^1 );
if (check_cancel( svars ))
goto out;
if (!(svars->chan->ops[t] & OP_EXPUNGE)) if (!(svars->chan->ops[t] & OP_EXPUNGE))
goto skip; goto skip;
int remote, only_new; int remote, only_new;
@ -1683,7 +1687,7 @@ static void
sync_close( sync_vars_t *svars, int t ) sync_close( sync_vars_t *svars, int t )
{ {
if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_pending[t] || if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_pending[t] ||
!(svars->state[t^1] & ST_SENT_NEW) || svars->new_pending[t^1]) (~svars->state[t^1] & (ST_SENT_NEW | ST_SENT_FLAGS)) || svars->new_pending[t^1] || svars->flags_pending[t^1])
return; return;
if (svars->state[t] & ST_CLOSING) if (svars->state[t] & ST_CLOSING)

Loading…
Cancel
Save