atom feed19 messages in com.selenic.mercurial-devel[PATCH 04 of 11] localrepo: decorate ...
FromSent OnAttachments
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Idan KamaraJul 16, 2011 7:34 am 
Adrian BuehlmannJul 16, 2011 9:03 am 
Matt MackallJul 18, 2011 1:12 pm 
Adrian BuehlmannJul 18, 2011 1:32 pm 
Matt MackallJul 18, 2011 2:29 pm 
Adrian BuehlmannJul 18, 2011 3:26 pm 
Idan KamaraJul 19, 2011 3:23 am 
Adrian BuehlmannJul 19, 2011 4:53 am 
Subject:[PATCH 04 of 11] localrepo: decorate dirstate() with filecache
From:Idan Kamara (idan@gmail.com)
Date:Jul 16, 2011 7:34:35 am
List:com.selenic.mercurial-devel

# HG changeset patch # User Idan Kamara <idan@gmail.com> # Date 1310826866 -10800 # Node ID 2fdd992fad65487bae9feeb873a1d7af4badc037 # Parent 87ba99602fd72793e5e9871bc3e775b4ddfffa57 localrepo: decorate dirstate() with filecache

And update its stat info when releasing repo.wlock(), right after writing it.

Also, invalidate the dirstate by deleting its attribute. This will force a stat by the decorator that actually checks if anything changed, rather than reading it again every time.

Note that prior to this, there was a single dirstate instance created for a localrepo. It was invalidated by calling dirstate.invalidated(), clearing its internal attributes.

As a consequence, the following construct is no longer safe:

ds = repo.dirstate # keep a reference to the repo's dirstate wlock = repo.wlock() try: ds.setparents(...) finally: wlock.release() # dirstate should be written here

Since it's possible that the dirstate was modified between lines #1 and #2, therefore changes to the old dirstate won't get written when the lock releases, because a new instance was created by the decorator.

diff -r 87ba99602fd7 -r 2fdd992fad65 mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Jul 16 17:34:26 2011 +0300 +++ b/mercurial/localrepo.py Sat Jul 16 17:34:26 2011 +0300 @@ -17,6 +17,7 @@ from lock import release import weakref, errno, os, time, inspect propertycache = util.propertycache +filecache = scmutil.filecache

class localrepository(repo.repository): capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey', @@ -185,7 +186,7 @@ def manifest(self): return manifest.manifest(self.sopener)

- @propertycache + @filecache('dirstate') def dirstate(self): warned = [0] def validate(node): @@ -784,6 +785,20 @@ self._branchcache = None # in UTF-8 self._branchcachetip = None

+ def invalidatedirstate(self): + '''Invalidates the dirstate, causing the next call to dirstate + to check if it was modified since the last time it was read, + rereading it if it has. + + This is different to dirstate.invalidate() that it doesn't always + rereads the dirstate. Use dirstate.invalidate() if you want to + explicitly read the dirstate again (i.e. restoring it to a previous + known good state).''' + try: + delattr(self, 'dirstate') + except AttributeError: + pass + def invalidate(self): for a in ("changelog", "manifest", "_bookmarks", "_bookmarkcurrent"): if a in self.__dict__: @@ -841,8 +856,12 @@ l.lock() return l

- l = self._lock(self.join("wlock"), wait, self.dirstate.write, - self.dirstate.invalidate, _('working directory of %s') % + def unlock(): + self.dirstate.write() + self._updatestatinfo('dirstate') + + l = self._lock(self.join("wlock"), wait, unlock, + self.invalidatedirstate, _('working directory of %s') % self.origroot) self._wlockref = weakref.ref(l) return l