commit ecb4c7ab07bb9678391833bb4786ff3a0df743fa
Author: Oswald Buddenhagen <[email protected]>
Date:   Sun Nov 24 15:58:32 2013 +0100

    propagate deletions with other flag changes
    
    less code duplication, more logical order of issued driver commands
    (especially after the next commit), and the "side effect" of letting the
    message expiration code see those deletions if they are asynchronous.

 src/sync.c |  104 +++++++++++++++++++++++----------------------------
 1 files changed, 47 insertions(+), 57 deletions(-)

diff --git a/src/sync.c b/src/sync.c
index 2501b8f..574a47c 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -100,6 +100,7 @@ make_flags( int flags, char *buf )
 #define S_EXPIRED      (1<<4)  /* the entry is expired (slave message removal 
confirmed) */
 #define S_EXPIRE       (1<<5)  /* the entry is being expired (slave message 
removal scheduled) */
 #define S_NEXPIRE      (1<<6)  /* temporary: new expiration state */
+#define S_DELETE       (1<<7)  /* ephemeral: flags propagation is a deletion */
 
 #define mvBit(in,ib,ob) ((unsigned char)(((unsigned)in) * (ob) / (ib)))
 
@@ -1106,9 +1107,8 @@ typedef struct {
        sync_rec_t *srec;
 } sync_rec_map_t;
 
-static void flags_set_del( int sts, void *aux );
-static void flags_set_sync( int sts, void *aux );
-static void flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t );
+static void flags_set( int sts, void *aux );
+static void flags_set_p2( sync_vars_t *svars, sync_rec_t *srec, int t );
 static int msgs_flags_set( sync_vars_t *svars, int t );
 static void msg_copied( int sts, int uid, copy_vars_t *vars );
 static void msg_copied_p2( sync_vars_t *svars, sync_rec_t *srec, int t, 
message_t *tmsg, int uid );
@@ -1298,12 +1298,8 @@ box_loaded( int sts, void *aux )
                                                        info( "Info: 
conflicting changes in (%d,%d)\n", srec->uid[M], srec->uid[S] );
                                                if (svars->chan->ops[t] & 
OP_DELETE) {
                                                        debug( "  %sing 
delete\n", str_hl[t] );
-                                                       svars->flags_total[t]++;
-                                                       stats( svars );
-                                                       fv = nfmalloc( 
sizeof(*fv) );
-                                                       fv->aux = AUX;
-                                                       fv->srec = srec;
-                                                       DRIVER_CALL(set_flags( 
svars->ctx[t], srec->msg[t], srec->uid[t], F_DELETED, 0, flags_set_del, fv ));
+                                                       srec->aflags[t] = 
F_DELETED;
+                                                       srec->status |= 
S_DELETE;
                                                } else {
                                                        debug( "  not %sing 
delete\n", str_hl[t] );
                                                }
@@ -1406,12 +1402,19 @@ box_loaded( int sts, void *aux )
                                continue;
                        aflags = srec->aflags[t];
                        dflags = srec->dflags[t];
-                       if ((t == S) && ((mvBit(srec->status, S_EXPIRE, 
S_EXPIRED) ^ srec->status) & S_EXPIRED)) {
-                               /* Derive deletion action from expiration 
state. */
-                               if (srec->status & S_NEXPIRE)
-                                       aflags |= F_DELETED;
-                               else
-                                       dflags |= F_DELETED;
+                       if (srec->status & S_DELETE) {
+                               if (!aflags) {
+                                       /* This deletion propagation goes the 
other way round. */
+                                       continue;
+                               }
+                       } else {
+                               if ((t == S) && ((mvBit(srec->status, S_EXPIRE, 
S_EXPIRED) ^ srec->status) & S_EXPIRED)) {
+                                       /* Derive deletion action from 
expiration state. */
+                                       if (srec->status & S_NEXPIRE)
+                                               aflags |= F_DELETED;
+                                       else
+                                               dflags |= F_DELETED;
+                               }
                        }
                        if ((svars->chan->ops[t] & OP_EXPUNGE) && 
(((srec->msg[t] ? srec->msg[t]->flags : 0) | aflags) & ~dflags & F_DELETED) &&
                            (!svars->ctx[t]->conf->trash || 
svars->ctx[t]->conf->trash_only_new))
@@ -1434,9 +1437,9 @@ box_loaded( int sts, void *aux )
                                fv->srec = srec;
                                fv->aflags = aflags;
                                fv->dflags = dflags;
-                               DRIVER_CALL(set_flags( svars->ctx[t], 
srec->msg[t], srec->uid[t], aflags, dflags, flags_set_sync, fv ));
+                               DRIVER_CALL(set_flags( svars->ctx[t], 
srec->msg[t], srec->uid[t], aflags, dflags, flags_set, fv ));
                        } else
-                               flags_set_sync_p2( svars, srec, t );
+                               flags_set_p2( svars, srec, t );
                }
        }
        for (t = 0; t < 2; t++) {
@@ -1540,24 +1543,7 @@ msgs_new_done( sync_vars_t *svars, int t )
 }
 
 static void
-flags_set_del( int sts, void *aux )
-{
-       SVARS_CHECK_RET_VARS(flag_vars_t);
-       switch (sts) {
-       case DRV_OK:
-               vars->srec->status |= S_DEL(t);
-               Fprintf( svars->jfp, "%c %d %d 0\n", "><"[t], 
vars->srec->uid[M], vars->srec->uid[S] );
-               vars->srec->uid[1-t] = 0;
-               break;
-       }
-       free( vars );
-       svars->flags_done[t]++;
-       stats( svars );
-       msgs_flags_set( svars, t );
-}
-
-static void
-flags_set_sync( int sts, void *aux )
+flags_set( int sts, void *aux )
 {
        SVARS_CHECK_RET_VARS(flag_vars_t);
        switch (sts) {
@@ -1566,7 +1552,7 @@ flags_set_sync( int sts, void *aux )
                        vars->srec->status |= S_DEL(t);
                else if (vars->dflags & F_DELETED)
                        vars->srec->status &= ~S_DEL(t);
-               flags_set_sync_p2( svars, vars->srec, t );
+               flags_set_p2( svars, vars->srec, t );
                break;
        }
        free( vars );
@@ -1576,28 +1562,32 @@ flags_set_sync( int sts, void *aux )
 }
 
 static void
-flags_set_sync_p2( sync_vars_t *svars, sync_rec_t *srec, int t )
+flags_set_p2( sync_vars_t *svars, sync_rec_t *srec, int t )
 {
-       int nflags, nex;
-
-       nflags = (srec->flags | srec->aflags[t]) & ~srec->dflags[t];
-       if (srec->flags != nflags) {
-               debug( "  pair(%d,%d): updating flags (%u -> %u; %sed)\n", 
srec->uid[M], srec->uid[S], srec->flags, nflags, str_hl[t] );
-               srec->flags = nflags;
-               Fprintf( svars->jfp, "* %d %d %u\n", srec->uid[M], 
srec->uid[S], nflags );
-       }
-       if (t == S) {
-               nex = (srec->status / S_NEXPIRE) & 1;
-               if (nex != ((srec->status / S_EXPIRED) & 1)) {
-                       if (nex && (svars->smaxxuid < srec->uid[S]))
-                               svars->smaxxuid = srec->uid[S];
-                       Fprintf( svars->jfp, "/ %d %d\n", srec->uid[M], 
srec->uid[S] );
-                       debug( "  pair(%d,%d): expired %d (commit)\n", 
srec->uid[M], srec->uid[S], nex );
-                       srec->status = (srec->status & ~S_EXPIRED) | (nex * 
S_EXPIRED);
-               } else if (nex != ((srec->status / S_EXPIRE) & 1)) {
-                       Fprintf( svars->jfp, "\\ %d %d\n", srec->uid[M], 
srec->uid[S] );
-                       debug( "  pair(%d,%d): expire %d (cancel)\n", 
srec->uid[M], srec->uid[S], nex );
-                       srec->status = (srec->status & ~S_EXPIRE) | (nex * 
S_EXPIRE);
+       if (srec->status & S_DELETE) {
+               debug( "  pair(%d,%d): resetting %s UID\n", srec->uid[M], 
srec->uid[S], str_ms[1-t] );
+               Fprintf( svars->jfp, "%c %d %d 0\n", "><"[t], srec->uid[M], 
srec->uid[S] );
+               srec->uid[1-t] = 0;
+       } else {
+               int nflags = (srec->flags | srec->aflags[t]) & ~srec->dflags[t];
+               if (srec->flags != nflags) {
+                       debug( "  pair(%d,%d): updating flags (%u -> %u; 
%sed)\n", srec->uid[M], srec->uid[S], srec->flags, nflags, str_hl[t] );
+                       srec->flags = nflags;
+                       Fprintf( svars->jfp, "* %d %d %u\n", srec->uid[M], 
srec->uid[S], nflags );
+               }
+               if (t == S) {
+                       int nex = (srec->status / S_NEXPIRE) & 1;
+                       if (nex != ((srec->status / S_EXPIRED) & 1)) {
+                               if (nex && (svars->smaxxuid < srec->uid[S]))
+                                       svars->smaxxuid = srec->uid[S];
+                               Fprintf( svars->jfp, "/ %d %d\n", srec->uid[M], 
srec->uid[S] );
+                               debug( "  pair(%d,%d): expired %d (commit)\n", 
srec->uid[M], srec->uid[S], nex );
+                               srec->status = (srec->status & ~S_EXPIRED) | 
(nex * S_EXPIRED);
+                       } else if (nex != ((srec->status / S_EXPIRE) & 1)) {
+                               Fprintf( svars->jfp, "\\ %d %d\n", 
srec->uid[M], srec->uid[S] );
+                               debug( "  pair(%d,%d): expire %d (cancel)\n", 
srec->uid[M], srec->uid[S], nex );
+                               srec->status = (srec->status & ~S_EXPIRE) | 
(nex * S_EXPIRE);
+                       }
                }
        }
 }

------------------------------------------------------------------------------
Sponsored by Intel(R) XDK 
Develop, test and display web and hybrid apps with a single code base.
Download it for free now!
http://pubads.g.doubleclick.net/gampad/clk?id=111408631&iu=/4140/ostg.clktrk
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to