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.
--- 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