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

Reply via email to