Re: Serious problems with multiple connections working with the same mailbox

Jerry Lundström <[email protected]> Sat, 17 Sep 2005 14:41:44 +0200
Newsgroups gmane.mail.imap.binc.devel
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------070903050907080602000508
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 8bit

Here is another way to do it and I would like someone else to check it.

This patch should invalidate the in-memory message cache before a 
process request get sent to the operator.

The cache gets valid once its done a successfull scan.

Scan is called at the point where mailbox.begin() is called so that the 
in-memory message cache is new and the same in the current command.

-- 
Jerry Lundström, System Developer
Section for IT and Media, Stockholms University, Sweden
+46 (0)8 16 19 99 / http://www.it.su.se

--------------070903050907080602000508
Content-Type: text/plain;
 name="cache_validity.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="cache_validity.patch"

diff -urN -x '*~' bincimap-1.2.13final.orig/src/bincimapd.cc bincimap-1.2.13final.cache/src/bincimapd.cc
--- bincimap-1.2.13final.orig/src/bincimapd.cc	2005-01-08 11:20:48.000000000 +0100
+++ bincimap-1.2.13final.cache/src/bincimapd.cc	2005-09-17 14:21:44.000000000 +0200
@@ -160,6 +160,7 @@
 
     session.addStatement();
     Depot *dep = session.getDepot();
+    dep->invalidateCache();
 
     switch (o->process(*dep, request)) {
     case Operator::OK:
diff -urN -x '*~' bincimap-1.2.13final.orig/src/depot.cc bincimap-1.2.13final.cache/src/depot.cc
--- bincimap-1.2.13final.orig/src/depot.cc	2005-06-14 21:45:44.000000000 +0200
+++ bincimap-1.2.13final.cache/src/depot.cc	2005-09-17 14:18:24.000000000 +0200
@@ -338,6 +338,14 @@
 }
 
 //--------------------------------------------------------------------
+void Depot::invalidateCache(void)
+{
+  for (vector<Mailbox *>::const_iterator i = backends.begin();
+       i != backends.end(); ++i)
+    (*i)->invalidateCache();
+}
+
+//--------------------------------------------------------------------
 Depot::iterator::iterator(void)
 {
   dirp = 0;
diff -urN -x '*~' bincimap-1.2.13final.orig/src/depot.h bincimap-1.2.13final.cache/src/depot.h
--- bincimap-1.2.13final.orig/src/depot.h	2005-06-14 21:45:44.000000000 +0200
+++ bincimap-1.2.13final.cache/src/depot.h	2005-09-17 14:17:08.000000000 +0200
@@ -130,6 +130,8 @@
     const std::string &getLastError(void) const;
     void setLastError(const std::string &error) const;
 
+    void invalidateCache(void);
+
     //--
     Depot(void);
     Depot(const std::string &name);
diff -urN -x '*~' bincimap-1.2.13final.orig/src/mailbox.h bincimap-1.2.13final.cache/src/mailbox.h
--- bincimap-1.2.13final.orig/src/mailbox.h	2005-01-08 11:20:48.000000000 +0100
+++ bincimap-1.2.13final.cache/src/mailbox.h	2005-09-17 14:12:52.000000000 +0200
@@ -105,8 +105,9 @@
       SQNR_MODE = 8
     };
 
-    virtual iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE) const = 0;
-    virtual iterator end(void) const = 0;
+    virtual void invalidateCache(void) = 0;
+    virtual iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE) = 0;
+    virtual iterator end(void) = 0;
 
     //-- Generic for one mailbox type
     virtual bool getStatus(const std::string &, Status &) const = 0;
diff -urN -x '*~' bincimap-1.2.13final.orig/src/maildir-scan.cc bincimap-1.2.13final.cache/src/maildir-scan.cc
--- bincimap-1.2.13final.orig/src/maildir-scan.cc	2005-02-08 21:30:22.000000000 +0100
+++ bincimap-1.2.13final.cache/src/maildir-scan.cc	2005-09-17 14:11:52.000000000 +0200
@@ -165,8 +165,10 @@
     if (oldnewstat.st_mtime == old_new_st_mtime
 	&& oldnewstat.st_ctime == old_new_st_ctime
 	&& oldcurstat.st_mtime == old_cur_st_mtime
-	&& oldcurstat.st_ctime == old_cur_st_ctime)
+	&& oldcurstat.st_ctime == old_cur_st_ctime) {
+      cacheValidity = true;
       return Success;
+    }
 
     old_cur_st_mtime = oldcurstat.st_mtime;
     old_cur_st_ctime = oldcurstat.st_ctime;
@@ -532,5 +534,6 @@
 
   firstscan = false;
   newMessages.clear();
+  cacheValidity = true;
   return Success;
 }
diff -urN -x '*~' bincimap-1.2.13final.orig/src/maildir.cc bincimap-1.2.13final.cache/src/maildir.cc
--- bincimap-1.2.13final.orig/src/maildir.cc	2005-01-08 11:20:48.000000000 +0100
+++ bincimap-1.2.13final.cache/src/maildir.cc	2005-09-17 14:20:06.000000000 +0200
@@ -173,18 +173,21 @@
 
 //------------------------------------------------------------------------
 Mailbox::iterator Maildir::begin(const SequenceSet &bset,
-				 unsigned int mod) const
+				 unsigned int mod)
 {
-  beginIterator = iterator((Maildir *)this, messages.begin(), bset, mod);
+  if(!cacheValidity && scan(false) == Success)
+    cacheValidity = true;
+
+  beginIterator = iterator(this, messages.begin(), bset, mod);
   beginIterator.reposition();
 
   return Mailbox::iterator(beginIterator);
 }
 
 //------------------------------------------------------------------------
-Mailbox::iterator Maildir::end(void) const
+Mailbox::iterator Maildir::end(void)
 {
-  endIterator = iterator((Maildir *)this, messages.end(),
+  endIterator = iterator(this, messages.end(),
 			 endIterator.bset, endIterator.mod);
   return Mailbox::iterator(endIterator);
 }
@@ -213,6 +216,7 @@
   selected = false;
   oldrecent = 0;
   oldexists = 0;
+  cacheValidity = false;
 }
 
 //------------------------------------------------------------------------
diff -urN -x '*~' bincimap-1.2.13final.orig/src/maildir.h bincimap-1.2.13final.cache/src/maildir.h
--- bincimap-1.2.13final.orig/src/maildir.h	2005-01-08 11:20:48.000000000 +0100
+++ bincimap-1.2.13final.cache/src/maildir.h	2005-09-17 14:13:51.000000000 +0200
@@ -115,8 +115,9 @@
  
     const std::string getTypeName(void) const;
 
-    Mailbox::iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE) const;
-    Mailbox::iterator end(void) const;
+    inline void invalidateCache(void);
+    Mailbox::iterator begin(const SequenceSet &bset, unsigned int mod = INCLUDE_EXPUNGED | SQNR_MODE);
+    Mailbox::iterator end(void);
 
     unsigned int getMaxUid(void) const;
     unsigned int getMaxSqnr(void) const;
@@ -204,7 +205,14 @@
 
     mutable bool uidnextchanged;
     mutable bool mailboxchanged;
+
+    bool cacheValidity;
   };
+
+  inline void Maildir::invalidateCache(void)
+  {
+    cacheValidity = false;
+  }
 }
 
 #endif

--------------070903050907080602000508--