commit a7c9438e0a3c2ae47e678011f13be7db1a4087f6 Author: Oswald Buddenhagen <o...@users.sf.net> Date: Sun Nov 17 19:57:01 2019 +0100
don't keep enumerating the same (not really) new messages we failed to up newmaxuid for messages we produced ourselves, so we would keep enumerating the same messages until we also propagated externally generated messages from that mailbox - which might have been never for the server side of archive/trash mailboxes. reported (way too long ago) by CCMAIL: Yuri D'Elia <wav...@thregr.org> src/run-tests.pl | 18 +++++++++--------- src/sync.c | 37 ++++++++++++++++++++++++++----------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/run-tests.pl b/src/run-tests.pl index 73a39a4..658cef2 100755 --- a/src/run-tests.pl +++ b/src/run-tests.pl @@ -53,7 +53,7 @@ my @X01 = ( 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "FT", 7, 7, "FT", 9, 9, "", 10, 10, "" ], [ 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 7, 7, "FT", 8, 8, "T", 9, 10, "", 10, 9, "" ], - [ 9, 0, 9, + [ 10, 0, 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 0, "", 7, 7, "FT", 0, 8, "", 10, 9, "", 9, 10, "" ], ); test("full", \@x01, \@X01, @O01); @@ -65,7 +65,7 @@ my @X02 = ( 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 9, 9, "", 10, 10, "" ], [ 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 9, 10, "", 10, 9, "" ], - [ 9, 0, 9, + [ 10, 0, 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 10, 9, "", 9, 10, "" ], ); test("full + expunge both", \@x01, \@X02, @O02); @@ -77,7 +77,7 @@ my @X03 = ( 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "FT", 7, 7, "FT", 9, 9, "", 10, 10, "" ], [ 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 9, 10, "", 10, 9, "" ], - [ 9, 0, 9, + [ 10, 0, 10, 1, 1, "F", 2, 2, "F", 3, 3, "FS", 4, 4, "", 5, 0, "T", 6, 0, "", 7, 0, "T", 10, 9, "", 9, 10, "" ], ); test("full + expunge slave", \@x01, \@X03, @O03); @@ -125,7 +125,7 @@ my @X07 = ( 1, 1, "F", 2, 2, "", 3, 3, "FS", 4, 4, "", 5, 5, "T", 6, 6, "F", 7, 7, "FT", 9, 9, "", 10, 10, "" ], [ 10, 1, 1, "", 2, 2, "F", 3, 3, "F", 4, 4, "", 5, 5, "", 7, 7, "", 8, 8, "", 9, 10, "", 10, 9, "" ], - [ 9, 0, 9, + [ 10, 0, 10, 1, 1, "", 2, 2, "", 3, 3, "", 4, 4, "", 5, 5, "", 6, 6, "", 7, 7, "", 8, 8, "", 10, 9, "", 9, 10, "" ], ); test("new", \@x01, \@X07, @O07); @@ -160,7 +160,7 @@ my @X11 = ( 1, 1, "", 2, 2, "*" ], [ 2, 3, 1, "*", 1, 2, "" ], - [ 2, 0, 1, + [ 2, 0, 2, 0, 1, "^", 1, 2, "", 2, 0, "^" ], ); test("max size", \@x10, \@X11, @O11); @@ -172,7 +172,7 @@ my @X22 = ( 1, 1, "", 2, 2, "*", 3, 3, "*" ], [ 2, 3, 1, "*", 1, 2, "" ], - [ 2, 0, 1, + [ 3, 0, 2, 3, 1, "", 1, 2, "", 2, 0, "^" ], ); test("slave max size", \@X11, \@X22, @O22); @@ -195,7 +195,7 @@ my @X31 = ( 1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ], [ 5, 1, 1, "F", 2, 2, "", 4, 3, "", 5, 4, "S", 6, 5, "" ], - [ 6, 3, 0, + [ 6, 3, 5, 1, 1, "F", 2, 2, "", 4, 3, "", 5, 4, "S", 6, 5, "" ], ); test("max messages", \@x30, \@X31, @O31); @@ -207,7 +207,7 @@ my @X32 = ( 1, 1, "F", 2, 2, "", 3, 3, "S", 4, 4, "", 5, 5, "S", 6, 6, "" ], [ 4, 1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ], - [ 6, 3, 0, + [ 6, 3, 4, 1, 1, "F", 4, 2, "", 5, 3, "S", 6, 4, "" ], ); test("max messages vs. unread", \@x30, \@X32, @O32); @@ -228,7 +228,7 @@ my @X51 = ( 1, 1, "S", 2, 2, "FS", 3, 3, "S", 4, 4, "", 5, 5, "", 6, 6, "" ], [ 6, 2, 2, "FS", 4, 4, "", 5, 5, "", 6, 6, "" ], - [ 6, 3, 0, + [ 6, 3, 6, 2, 2, "FS", 4, 4, "", 5, 5, "", 6, 6, "" ], ); test("max messages + expunge", \@x50, \@X51, @O51); diff --git a/src/sync.c b/src/sync.c index fee5e7d..7fced0c 100644 --- a/src/sync.c +++ b/src/sync.c @@ -272,6 +272,8 @@ match_tuids( sync_vars_t *svars, int t, message_t *msgs ) srec->msg[t] = tmsg; ntmsg = tmsg->next; srec->uid[t] = tmsg->uid; + if (tmsg->uid == svars->newmaxuid[t] + 1) + svars->newmaxuid[t] = tmsg->uid; srec->status = 0; srec->tuid[0] = 0; } @@ -869,7 +871,7 @@ load_state( sync_vars_t *svars ) (tn = 0, (sscanf( buf + 2, "%u %u %n", &t1, &t2, &tn ) < 2) || !tn || (ll - (uint)tn != TUIDL + 2)) : c == 'S' || c == '!' ? (sscanf( buf + 2, "%u", &t1 ) != 1) : - c == 'F' || c == 'T' || c == '+' || c == '&' || c == '-' || c == '=' || c == '|' ? + c == 'N' || c == 'F' || c == 'T' || c == '+' || c == '&' || c == '-' || c == '=' || c == '|' ? (sscanf( buf + 2, "%u %u", &t1, &t2 ) != 2) : (sscanf( buf + 2, "%u %u %u", &t1, &t2, &t3 ) != 3)) { @@ -878,6 +880,8 @@ load_state( sync_vars_t *svars ) } if (c == 'S') svars->maxuid[t1] = svars->newmaxuid[t1]; + else if (c == 'N') + svars->newmaxuid[t1] = t2; else if (c == 'F') svars->newuid[t1] = t2; else if (c == 'T') @@ -891,10 +895,6 @@ load_state( sync_vars_t *svars ) srec = nfmalloc( sizeof(*srec) ); srec->uid[M] = t1; srec->uid[S] = t2; - if (svars->newmaxuid[M] < t1) - svars->newmaxuid[M] = t1; - if (svars->newmaxuid[S] < t2) - svars->newmaxuid[S] = t2; debug( " new entry(%u,%u)\n", t1, t2 ); srec->msg[M] = srec->msg[S] = NULL; srec->status = S_PENDING; @@ -938,12 +938,16 @@ load_state( sync_vars_t *svars ) case '<': debug( "master now %u\n", t3 ); srec->uid[M] = t3; + if (t3 == svars->newmaxuid[M] + 1) + svars->newmaxuid[M] = t3; srec->status &= ~S_PENDING; srec->tuid[0] = 0; break; case '>': debug( "slave now %u\n", t3 ); srec->uid[S] = t3; + if (t3 == svars->newmaxuid[S] + 1) + svars->newmaxuid[S] = t3; srec->status &= ~S_PENDING; srec->tuid[0] = 0; break; @@ -1611,8 +1615,6 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux srec->msg[1-t] = tmsg; srec->msg[t] = NULL; tmsg->srec = srec; - if (svars->newmaxuid[1-t] < tmsg->uid) - svars->newmaxuid[1-t] = tmsg->uid; jFprintf( svars, "+ %u %u\n", srec->uid[M], srec->uid[S] ); debug( " -> pair(%u,%u) created\n", srec->uid[M], srec->uid[S] ); } @@ -1638,7 +1640,15 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux } } } + // We do this outside the condition block above, so new messages that are + // actually a result of syncing are also skipped over in subsequent runs + // (this only matters when the instant tracking is disturbed by delivery + // of new messages while we are syncing). + if (svars->newmaxuid[1-t] < tmsg->uid && (svars->chan->ops[t] & OP_NEW)) + svars->newmaxuid[1-t] = tmsg->uid; } + // This can be done outside the (approximately) idempotent loop. + jFprintf( svars, "N %d %u\n", 1-t, svars->newmaxuid[1-t] ); } if ((svars->chan->ops[S] & (OP_NEW|OP_RENEW|OP_FLAGS)) && svars->chan->max_messages) { @@ -1844,6 +1854,8 @@ msg_copied( int sts, uint uid, copy_vars_t *vars ) debug( " -> new UID %u on %s\n", uid, str_ms[t] ); jFprintf( svars, "%c %u %u %u\n", "<>"[t], vars->srec->uid[M], vars->srec->uid[S], uid ); vars->srec->uid[t] = uid; + if (uid == svars->newmaxuid[t] + 1) + svars->newmaxuid[t] = uid; vars->srec->status &= ~S_PENDING; vars->srec->tuid[0] = 0; } @@ -1915,10 +1927,6 @@ msgs_copied( sync_vars_t *svars, int t ) if (svars->new_pending[t]) goto out; - if (svars->maxuid[1-t] != svars->newmaxuid[1-t]) { - svars->maxuid[1-t] = svars->newmaxuid[1-t]; - jFprintf( svars, "S %d\n", 1-t ); - } sync_close( svars, 1-t ); if (check_cancel( svars )) goto out; @@ -2191,6 +2199,13 @@ box_closed_p2( sync_vars_t *svars, int t ) debug( "max expired uid on master is now %u\n", svars->mmaxxuid ); jFprintf( svars, "! %u\n", svars->mmaxxuid ); + for (t = 0; t < 2; t++) { + if (svars->maxuid[t] != svars->newmaxuid[t]) { + svars->maxuid[t] = svars->newmaxuid[t]; + jFprintf( svars, "S %d\n", t ); + } + } + save_state( svars ); sync_bail( svars ); _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel