[PATCH 3 of 5] branchmap: acquires lock before writting the rev branch cache

Yuya Nishihara yuya at tcha.org
Sun Aug 7 07:21:38 EDT 2016


On Sat, 06 Aug 2016 01:02:55 +0200, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david at ens-lyon.org>
> # Date 1470401836 -7200
> #      Fri Aug 05 14:57:16 2016 +0200
> # Node ID 84885aeec2e442d18dcb70fcce2d65dd9fafbf91
> # Parent  fa3f05a4219c4ea6b9bc9682f258e4418b36c265
> # EXP-Topic vfsward
> branchmap: acquires lock before writting the rev branch cache
> 
> We now attempt to acquire a lock and write the branch cache within that lock.
> This would prevent cache corruption when multiple processes try to write the cache
> at the same time.

(+CC Durham, Mads)

I wonder if revbranchcache is designed to not take a lock. 9347c15d8136 says
corruption can be recovered.

> --- a/mercurial/branchmap.py	Fri Aug 05 14:54:46 2016 +0200
> +++ b/mercurial/branchmap.py	Fri Aug 05 14:57:16 2016 +0200
> @@ -470,8 +470,10 @@ class revbranchcache(object):
>      def write(self, tr=None):
>          """Save branch cache if it is dirty."""
>          repo = self._repo
> -        if True:
> +        wlock = None
> +        try:
>              if self._rbcnamescount < len(self._names):
> +                wlock = repo.wlock(wait=False)
>                  try:
>                      if self._rbcnamescount != 0:
>                          f = repo.vfs.open(_rbcnames, 'ab')
> @@ -501,6 +503,7 @@ class revbranchcache(object):
>  
>              start = self._rbcrevslen * _rbcrecsize
>              if start != len(self._rbcrevs):
> +                wlock = repo.wlock(wait=False)
>                  revs = min(len(repo.changelog),
>                             len(self._rbcrevs) // _rbcrecsize)
>                  try:
> @@ -521,3 +524,8 @@ class revbranchcache(object):
>                                    inst)
>                      return
>                  self._rbcrevslen = revs
> +        except error.LockHeld as inst:
> +            repo.ui.debug("couldn't write revision branch cache: %s\n" % inst)
> +        finally:
> +            if wlock is not None:
> +                wlock.release()

wlock.held wouldn't be decremented appropriately if you'd take two wlocks.


More information about the Mercurial-devel mailing list