commit a7c9438e0a3c2ae47e678011f13be7db1a4087f6
Author: Oswald Buddenhagen <[email protected]>
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 <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel