Mercurial > hg-stable
changeset 29756:0d588332ad2c
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.
author | Pierre-Yves David <pierre-yves.david@ens-lyon.org> |
---|---|
date | Fri, 05 Aug 2016 14:57:16 +0200 |
parents | 9f3c49ee4486 |
children | 3b184adfb5be |
files | mercurial/branchmap.py tests/test-branches.t |
diffstat | 2 files changed, 22 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- 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()
--- 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