From 8df1f5dd646d165a9a8fb90f57c3a8872ab3ce7a Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Wed, 8 Jul 2020 14:37:57 +0200 Subject: [PATCH] re-nest conditions for syncing new messages this makes the logic easier to follow and document in place. also, make the comments actually match reality. --- src/sync.c | 104 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/src/sync.c b/src/sync.c index 64ecaa3..f274058 100644 --- a/src/sync.c +++ b/src/sync.c @@ -1572,14 +1572,9 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux } } - debug( "synchronizing new entries\n" ); for (t = 0; t < 2; t++) { + debug( "synchronizing new messages on %s\n", str_fn[1-t] ); for (tmsg = svars->msgs[1-t]; tmsg; tmsg = tmsg->next) { - // If new have no srec, the message is always New. If we have a srec: - // - message is paired or expired => ignore - // - message was skipped => ReNew - // - message was attempted, but is still pending or failed => 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. @@ -1588,47 +1583,66 @@ box_loaded( int sts, message_t *msgs, int total_msgs, int recent_msgs, void *aux // in case of interruption - in particular skipping big messages would otherwise // up the limit too early. srec = tmsg->srec; - if (srec ? (((srec->status & S_PENDING) && (svars->chan->ops[t] & OP_NEW)) || - ((srec->status & S_SKIPPED) && (svars->chan->ops[t] & OP_RENEW))) - : svars->newmaxuid[1-t] < tmsg->uid && (svars->chan->ops[t] & OP_NEW)) { - debug( "new message %u on %s\n", tmsg->uid, str_fn[1-t] ); + if (srec) { + if (srec->status & S_SKIPPED) { + // The message was skipped due to being too big. + if (!(svars->chan->ops[t] & OP_RENEW)) + continue; + } else { + if (!(svars->chan->ops[t] & OP_NEW)) + continue; + if (!(srec->status & S_PENDING)) + continue; // Nothing to do - the message is paired or expired + // Propagation was scheduled, but we got interrupted + } + debug( "unpropagated old message %u\n", tmsg->uid ); + if ((svars->chan->ops[t] & OP_EXPUNGE) && (tmsg->flags & F_DELETED)) { - if (srec) { - JLOG( "- %u %u", (srec->uid[F], srec->uid[N]), "killing - would be expunged anyway" ); - tmsg->srec = NULL; - srec->status = S_DEAD; - } else { - debug( "-> ignoring - would be expunged anyway\n" ); - } + JLOG( "- %u %u", (srec->uid[F], srec->uid[N]), "killing - would be expunged anyway" ); + tmsg->srec = NULL; + srec->status = S_DEAD; + continue; + } + } else { + if (!(svars->chan->ops[t] & OP_NEW)) + continue; + if (tmsg->uid <= svars->newmaxuid[1-t]) { + // The message should be already paired. It's not, so it was: + // - previously paired, but the entry was expired and pruned => ignore + // - attempted, but failed => ignore (the wisdom of this is debatable) + // - ignored, as it would have been expunged anyway => ignore (even if undeleted) + continue; + } + debug( "new message %u\n", tmsg->uid ); + + if ((svars->chan->ops[t] & OP_EXPUNGE) && (tmsg->flags & F_DELETED)) { + debug( "-> ignoring - would be expunged anyway\n" ); + continue; + } + + srec = nfcalloc( sizeof(*srec) ); + *svars->srecadd = srec; + svars->srecadd = &srec->next; + svars->nsrecs++; + srec->status = S_PENDING; + srec->uid[1-t] = tmsg->uid; + srec->msg[1-t] = tmsg; + tmsg->srec = srec; + if (svars->newmaxuid[1-t] < tmsg->uid) + svars->newmaxuid[1-t] = tmsg->uid; + JLOG( "+ %u %u", (srec->uid[F], srec->uid[N]), "fresh" ); + } + if ((tmsg->flags & F_FLAGGED) || tmsg->size <= svars->chan->stores[t]->max_size) { + if (srec->status != S_PENDING) { + srec->status = S_PENDING; + JLOG( "~ %u %u %u", (srec->uid[F], srec->uid[N], srec->status), "was too big" ); + } + } else { + if (srec->status == S_SKIPPED) { + debug( "-> still too big\n" ); } else { - if (srec) { - debug( "-> pair(%u,%u) exists\n", srec->uid[F], srec->uid[N] ); - } else { - srec = nfcalloc( sizeof(*srec) ); - *svars->srecadd = srec; - svars->srecadd = &srec->next; - svars->nsrecs++; - srec->status = S_PENDING; - srec->uid[1-t] = tmsg->uid; - srec->msg[1-t] = tmsg; - tmsg->srec = srec; - if (svars->newmaxuid[1-t] < tmsg->uid) - svars->newmaxuid[1-t] = tmsg->uid; - JLOG( "+ %u %u", (srec->uid[F], srec->uid[N]), "fresh" ); - } - if ((tmsg->flags & F_FLAGGED) || tmsg->size <= svars->chan->stores[t]->max_size) { - if (srec->status != S_PENDING) { - srec->status = S_PENDING; - JLOG( "~ %u %u %u", (srec->uid[F], srec->uid[N], srec->status), "was too big" ); - } - } else { - if (srec->status == S_SKIPPED) { - debug( "-> still too big\n" ); - } else { - srec->status = S_SKIPPED; - JLOG( "~ %u %u %u", (srec->uid[F], srec->uid[N], srec->status), "skipping - too big" ); - } - } + srec->status = S_SKIPPED; + JLOG( "~ %u %u %u", (srec->uid[F], srec->uid[N], srec->status), "skipping - too big" ); } } }