# HG changeset patch # User Pierre-Yves David # Date 1470401836 -7200 # Node ID 0d588332ad2c200e4cc1f5ea1ac900f5afa6711b # Parent 9f3c49ee44865c5c38f869d62dee3cd49341ee32 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. diff -r 9f3c49ee4486 -r 0d588332ad2c mercurial/branchmap.py --- 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 @@ 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,8 @@ start = self._rbcrevslen * _rbcrecsize if start != len(self._rbcrevs): + if wlock is None: + wlock = repo.wlock(wait=False) revs = min(len(repo.changelog), len(self._rbcrevs) // _rbcrecsize) try: @@ -521,3 +525,8 @@ inst) return self._rbcrevslen = revs + except error.LockError as inst: + repo.ui.debug("couldn't write revision branch cache: %s\n" % inst) + finally: + if wlock is not None: + wlock.release() diff -r 9f3c49ee4486 -r 0d588332ad2c tests/test-branches.t --- a/tests/test-branches.t Fri Aug 05 14:54:46 2016 +0200 +++ b/tests/test-branches.t Fri Aug 05 14:57:16 2016 +0200 @@ -554,6 +554,18 @@ $ rmdir .hg/cache/rbc-revs-v1 $ mv .hg/cache/rbc-revs-v1_ .hg/cache/rbc-revs-v1 +no errors when wlock cannot be acquired + +#if unix-permissions + $ mv .hg/cache/rbc-revs-v1 .hg/cache/rbc-revs-v1_ + $ rm -f .hg/cache/branch* + $ chmod 555 .hg + $ hg head a -T '{rev}\n' + 5 + $ chmod 755 .hg + $ mv .hg/cache/rbc-revs-v1_ .hg/cache/rbc-revs-v1 +#endif + recovery from invalid cache revs file with trailing data $ echo >> .hg/cache/rbc-revs-v1 $ rm -f .hg/cache/branch* && hg head a -T '{rev}\n' --debug