]> git.g-eek.se Git - interimap.git/commitdiff
bugfix: new messages can be received while FETCHing new messages.
authorGuilhem Moulin <guilhem@fripost.org>
Fri, 24 Jul 2015 15:29:52 +0000 (17:29 +0200)
committerGuilhem Moulin <guilhem@fripost.org>
Fri, 24 Jul 2015 15:35:29 +0000 (17:35 +0200)
lib/Net/IMAP/Sync.pm

index 1aceb7067a55f16d38c867d23ce0b0ed80baedd1..fc1ab813f7f87eec8f6e8e3e2983568c78e87242 100644 (file)
@@ -651,12 +651,12 @@ sub append($$$@) {
     my @uids;
     foreach (split /,/, $uidset) {
         if (/\A([0-9]+)\z/) {
-            $UIDNEXT = $1 + 1 if $UIDNEXT < $1;
+            $UIDNEXT = $1 + 1 if $UIDNEXT <= $1;
             push @uids, $1;
         } elsif (/\A([0-9]+):([0-9]+)\z/) {
             my ($min, $max) = $1 <= $2 ? ($1,$2) : ($2,$1);
             push @uids, ($min .. $max);
-            $UIDNEXT = $max + 1 if $UIDNEXT < $max;
+            $UIDNEXT = $max + 1 if $UIDNEXT <= $max;
         } else {
             $self->panic($_);
         }
@@ -917,36 +917,43 @@ sub pull_new_messages($$@) {
     my $attrs = join ' ', qw/MODSEQ FLAGS INTERNALDATE/, @attrs, 'BODY.PEEK[]';
 
     my $mailbox = $self->{_SELECTED} // $self->panic();
-    my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} // 1;
-
-    my $range = '';
-    my $first;
-    foreach my $uid (@ignore) {
-        if ($since < $uid) {
-            $first //= $since;
-            $range .= ',' if $range ne '';
-            $range .= $since;
-            $range .= ':'.($uid-1) if $since < $uid-1;
-            $since = $uid+1;
-        }
-        elsif ($since == $uid) {
-            $since++;
-        }
-    }
-
-    $first //= $since;
-    $range .= ',' if $range ne '';
-    # 2^32-1: don't use '*' since the highest UID can be known already
-    $range .= "$since:4294967295";
-
-    my $UIDNEXT = $self->{_CACHE}->{$mailbox}->{UIDNEXT};
-    $self->panic() unless defined $UIDNEXT and $UIDNEXT > 0; # sanity check
 
-    $self->_send("UID FETCH $range ($attrs)", $callback) if $first < $UIDNEXT;;
+    my $UIDNEXT;
+    do {
+        my $range = '';
+        my $first;
+        my $since = $self->{_PCACHE}->{$mailbox}->{UIDNEXT} // 1;
+        foreach my $uid (@ignore) {
+            if ($since < $uid) {
+                $first //= $since;
+                $range .= ',' if $range ne '';
+                $range .= $since;
+                $range .= ':'.($uid-1) if $since < $uid-1;
+                $since = $uid+1;
+            }
+            elsif ($since == $uid) {
+                $since++;
+            }
+        }
 
-    # update the persistent cache for UIDNEXT (not for HIGHESTMODSEQ
-    # since there might be pending updates)
-    $self->set_cache($mailbox, %{$self->{_CACHE}->{$mailbox}}{UIDNEXT});
+        $first //= $since;
+        $range .= ',' if $range ne '';
+        # 2^32-1: don't use '*' since the highest UID can be known already
+        $range .= "$since:4294967295";
+
+        $UIDNEXT = $self->{_CACHE}->{$mailbox}->{UIDNEXT} // $self->panic(); # sanity check
+        $self->_send("UID FETCH $range ($attrs)", sub(%) {
+            my %mail = @_;
+            $UIDNEXT = $mail{UID} + 1 if $UIDNEXT <= $mail{UID};
+            $callback->(%mail) if defined $callback;
+        }) if $first < $UIDNEXT;
+
+        # update the persistent cache for UIDNEXT (not for HIGHESTMODSEQ
+        # since there might be pending updates)
+        $self->set_cache($mailbox, UIDNEXT => $UIDNEXT);
+    }
+    # loop if new messages were received in the meantime
+    while ($UIDNEXT < $self->{_CACHE}->{$mailbox}->{UIDNEXT});
 }
 
 
@@ -1461,7 +1468,7 @@ sub _resp($$;$$$) {
                     # always present, cf RFC 3501 section 6.4.8
                     $mail{UID} = $1;
                     # the actual UIDNEXT is *at least* that
-                    $cache->{UIDNEXT} = $1+1 if !defined $cache->{UIDNEXT} or $cache->{UIDNEXT} < $1;
+                    $cache->{UIDNEXT} = $1+1 if !defined $cache->{UIDNEXT} or $cache->{UIDNEXT} <= $1;
                 }
                 if (s/\AMODSEQ \(([0-9]+)\)//) { # RFC 4551/7162 CONDSTORE/QRESYNC
                     # always present in unsolicited FETCH responses if QRESYNC has been enabled