Commits

Brodie Rao  committed c0627cd

Refreshing queue

  • Participants
  • Parent commits b599d57

Comments (0)

Files changed (1)

 # HG changeset patch
-# Parent c38c3fdc8b9317ba09e03ab09364c3800da7c50c
+# Parent da48091f55e19d9f89ce3756c32f66dc882c1a96
 localrepo: add store.cachefps config option to cache file handles
 
 When store.cachefps is set to True, all files opened from .hg/store stay open
                      return util.atomictempfile(f, mode, self.createmode)
                  try:
                      if 'w' in mode:
-+                        self._invalidate(f)
++                        #self._invalidate(f)
                          util.unlink(f)
                          nlink = 0
                      else:
                      if self._trustnlink is None:
                          self._trustnlink = nlink > 1 or util.checknlink(f)
                      if nlink > 1 or not self._trustnlink:
-+                        self._invalidate(f)
++                        #self._invalidate(f)
                          util.rename(util.mktempcopy(f), f)
 -        fp = util.posixfile(f, mode)
 +        fp = self._open(f, mode)
          if nlink == 0:
              self._fixfilemode(f)
          return fp
-@@ -400,6 +412,72 @@ class vfs(abstractvfs):
+@@ -400,6 +412,97 @@ class vfs(abstractvfs):
          else:
              return self.base
  
 +        super(cachedvfs, self).__init__(*args, **kwargs)
 +        self._fpcache = {}
 +
++    def _zombiefile(self, f, mode):
++        fp = _zombiefile(f, mode)
++        st = os.stat(f)
++        self._fpcache[(f, mode)] = (fp, st)
++        return fp
++
 +    def _open(self, f, mode):
-+        fp = self._fpcache.get((f, mode))
-+        if fp is not None:
-+            try:
-+                fp.flush()
-+                fp.seek(0)
-+            except IOError, e:
-+                del self._fpcache[(f, mode)]
-+                if e.errno == errno.ESTALE:
-+                    fp = None
-+                else:
-+                    raise
-+        if fp is None:
-+            fp = _zombiefile(f, mode)
-+            self._fpcache[(f, mode)] = fp
++        if mode not in ('r', 'rb'):
++            return super(cachedvfs, self)._open(f, mode)
++
++        entry = self._fpcache.get((f, mode))
++        if entry is None:
++            return self._zombiefile(f, mode)
++
++        fp, st = entry
++        try:
++            st2 = os.stat(f)
++        except OSError, e:
++            del self._fpcache[(f, mode)]
++            if e.errno != errno.ENOENT:
++                raise
++            fp.close()
++            return self._zombiefile(f, mode)
++
++        if not os.path.samestat(st, st2):
++            del self._fpcache[(f, mode)]
++            fp.close()
++            return self._zombiefile(f, mode)
++
++        try:
++            fp.flush()
++            fp.seek(0)
++        except IOError, e:
++            del self._fpcache[(f, mode)]
++            if e.errno != errno.ESTALE:
++                raise
++            fp.close()
++            return self._zombiefile(f, mode)
++
 +        return fp
 +
 +    def _invalidate(self, f):
 +        for key in [k for k in self._fpcache if k[0] == f]:
-+            self._fpcache.pop(key)._close()
++            fp, st = self._fpcache.pop(key)
++            fp._close()
 +
 +    def close(self):
-+        for fp in self._fpcache.itervalues():
-+            fp._close()
++        for entry in self._fpcache.itervalues():
++            entry[0]._close()
 +        self._fpcache = {}
 +
  opener = vfs
  
  class auditvfs(object):
-@@ -424,6 +502,9 @@ class filtervfs(abstractvfs, auditvfs):
+@@ -424,6 +527,9 @@ class filtervfs(abstractvfs, auditvfs):
      def __call__(self, path, *args, **kwargs):
          return self.vfs(self._filter(path), *args, **kwargs)
  
      def join(self, path):
          if path:
              return self.vfs.join(self._filter(path))
-@@ -443,6 +524,8 @@ class readonlyvfs(abstractvfs, auditvfs)
+@@ -443,6 +549,8 @@ class readonlyvfs(abstractvfs, auditvfs)
              raise util.Abort('this vfs is read only')
          return self.vfs(path, mode, *args, **kw)