commit 1ea2e69aa7be3f7b8169ded9068d6c8854391158
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Sun Mar 19 11:35:57 2017 +0100

    fix maxuid tracking
    
    newmaxuid represents the highest UID for which a sync entry was created,
    while maxuid represents the end of the range which is guaranteed to have
    been propagated. that means that the former needs to be instantly
    incremented (and logged), while the latter must not be touched until the
    entire new message sync completes. this matters particularly in the case
    of resuming an interrupted run, where sync entry creation must resume
    exactly where it left off, while loading the box must use the old limit
    to ensure that all messages are available for actual propagation.

 src/sync.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/src/sync.c b/src/sync.c
index 15411a3..a6584e0 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -826,9 +826,9 @@ load_state( sync_vars_t *svars )
                                buf[t] = 0;
                                if ((c = buf[0]) == '#' ?
                                      (t3 = 0, (sscanf( buf + 2, "%d %d %n", 
&t1, &t2, &t3 ) < 2) || !t3 || (t - t3 != TUIDL + 2)) :
-                                     c == '!' ?
+                                     c == 'S' || c == '!' ?
                                        (sscanf( buf + 2, "%d", &t1 ) != 1) :
-                                       c == 'S' || c == 'F' || c == 'T' || c 
== '+' || c == '&' || c == '-' || c == '|' || c == '/' || c == '\\' ?
+                                       c == 'F' || c == 'T' || c == '+' || c 
== '&' || c == '-' || c == '|' || c == '/' || c == '\\' ?
                                          (sscanf( buf + 2, "%d %d", &t1, &t2 ) 
!= 2) :
                                          (sscanf( buf + 2, "%d %d %d", &t1, 
&t2, &t3 ) != 3))
                                {
@@ -836,7 +836,7 @@ load_state( sync_vars_t *svars )
                                        goto jbail;
                                }
                                if (c == 'S')
-                                       svars->maxuid[t1] = t2;
+                                       svars->maxuid[t1] = 
svars->newmaxuid[t1];
                                else if (c == 'F')
                                        svars->newuid[t1] = t2;
                                else if (c == 'T')
@@ -1569,15 +1569,18 @@ box_loaded( int sts, void *aux )
        debug( "synchronizing new entries\n" );
        for (t = 0; t < 2; t++) {
                for (tmsg = svars->ctx[1-t]->msgs; tmsg; tmsg = tmsg->next) {
-                       /* If we have a srec:
-                        * - message is old (> 0) or expired (0) => ignore
-                        * - message was skipped (-1) => ReNew
-                        * - message was attempted, but failed (-2) => New
-                        * If new have no srec, the message is always New. If 
messages were previously ignored
-                        * due to being excessive, they would now appear to be 
newer than the messages that
-                        * got actually synced, so make sure to look only at 
the newest ones. As some messages
-                        * may be already propagated before an interruption, 
and maxuid logging is delayed,
-                        * we need to track the newmaxuid separately. */
+                       // If new have no srec, the message is always New. If 
we have a srec:
+                       // - message is old (> 0) or expired (0) => ignore
+                       // - message was skipped (-1) => ReNew
+                       // - message was attempted, but failed (-2) => New
+                       //
+                       // If messages were previously ignored due to being 
excessive, they would now
+                       // appear to be newer than the messages that got 
actually synced, so increment
+                       // newmaxuid immediately to make sure we always look 
only at the newest ones.
+                       // However, committing it to maxuid must be delayed 
until all messages were
+                       // propagated, to ensure that all pending messages are 
still loaded next time
+                       // in case of interruption - in particular skipping big 
messages would otherwise
+                       // up the limit too early.
                        srec = tmsg->srec;
                        if (srec ? srec->uid[t] < 0 && (svars->chan->ops[t] & 
(srec->uid[t] == -1 ? OP_RENEW : OP_NEW))
                                 : svars->newmaxuid[1-t] < tmsg->uid && 
(svars->chan->ops[t] & OP_NEW)) {
@@ -1606,12 +1609,6 @@ box_loaded( int sts, void *aux )
                                                jFprintf( svars, "+ %d %d\n", 
srec->uid[M], srec->uid[S] );
                                                debug( "  -> pair(%d,%d) 
created\n", srec->uid[M], srec->uid[S] );
                                        }
-                                       if (svars->maxuid[1-t] < tmsg->uid) {
-                                               /* We do this here for 
simplicity. However, logging must be delayed until
-                                                * all messages were 
propagated, as skipped messages could otherwise be
-                                                * logged before the 
propagation of messages with lower UIDs completes. */
-                                               svars->maxuid[1-t] = tmsg->uid;
-                                       }
                                        if ((tmsg->flags & F_FLAGGED) || 
tmsg->size <= svars->chan->stores[t]->max_size) {
                                                if (tmsg->flags) {
                                                        srec->flags = 
tmsg->flags;
@@ -1923,7 +1920,10 @@ msgs_copied( sync_vars_t *svars, int t )
        if (svars->new_pending[t])
                goto out;
 
-       jFprintf( svars, "S %d %d\n", 1-t, svars->maxuid[1-t] );
+       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;

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to