ensure sequencing of message propagation and store closing

by putting the message propagation last, d3f634702 uncovered a
long-standing problem: we might have closed the source store before all
messages were propagated from it.
This commit is contained in:
Oswald Buddenhagen 2013-12-11 16:25:30 +01:00
parent c47ee1c8c4
commit 5a21042e98

View File

@ -204,6 +204,7 @@ static int check_cancel( sync_vars_t *svars );
#define ST_CANCELED (1<<9) #define ST_CANCELED (1<<9)
#define ST_SELECTED (1<<10) #define ST_SELECTED (1<<10)
#define ST_DID_EXPUNGE (1<<11) #define ST_DID_EXPUNGE (1<<11)
#define ST_CLOSING (1<<12)
static void static void
@ -1594,7 +1595,12 @@ msgs_copied( sync_vars_t *svars, int t )
if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < svars->new_total[t]) if (!(svars->state[t] & ST_SENT_NEW) || svars->new_done[t] < svars->new_total[t])
return; return;
sync_ref( svars );
Fprintf( svars->jfp, "%c %d\n", ")("[t], svars->maxuid[1-t] ); Fprintf( svars->jfp, "%c %d\n", ")("[t], svars->maxuid[1-t] );
sync_close( svars, 1-t );
if (check_cancel( svars ))
goto out;
if (svars->state[t] & ST_FIND_NEW) { if (svars->state[t] & ST_FIND_NEW) {
debug( "finding just copied messages on %s\n", str_ms[t] ); debug( "finding just copied messages on %s\n", str_ms[t] );
@ -1602,6 +1608,9 @@ msgs_copied( sync_vars_t *svars, int t )
} else { } else {
msgs_new_done( svars, t ); msgs_new_done( svars, t );
} }
out:
sync_deref( svars );
} }
static void static void
@ -1775,10 +1784,14 @@ static void box_closed_p2( sync_vars_t *svars, int t );
static void 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)) || if ((~svars->state[t] & (ST_FOUND_NEW|ST_SENT_TRASH)) || svars->trash_done[t] < svars->trash_total[t] ||
svars->trash_done[t] < svars->trash_total[t]) !(svars->state[1-t] & ST_SENT_NEW) || svars->new_done[1-t] < svars->new_total[1-t])
return; return;
if (svars->state[t] & ST_CLOSING)
return;
svars->state[t] |= ST_CLOSING;
if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & ST_TRASH_BAD)*/) { if ((svars->chan->ops[t] & OP_EXPUNGE) /*&& !(svars->state[t] & ST_TRASH_BAD)*/) {
debug( "expunging %s\n", str_ms[t] ); debug( "expunging %s\n", str_ms[t] );
svars->drv[t]->close( svars->ctx[t], box_closed, AUX ); svars->drv[t]->close( svars->ctx[t], box_closed, AUX );