Mercurial > hg
changeset 33437:0720e6265c8a
reposvfs: add a ward to check if locks are properly taken
we wrap 'repo.svfs.audit' to check for the store lock when accessing file in
'.hg/store' for writing. This caught a couple of instance where the transaction
was released after the lock, we should probably have a dedicated checker for
that case.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Mon, 08 Aug 2016 18:14:42 +0200 |
parents | 9bb4decd43b0 |
children | 8056481caa81 |
files | mercurial/localrepo.py tests/test-devel-warnings.t |
diffstat | 2 files changed, 33 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/localrepo.py Tue Jul 11 12:38:17 2017 +0200 +++ b/mercurial/localrepo.py Mon Aug 08 18:14:42 2016 +0200 @@ -423,6 +423,12 @@ self.svfs = self.store.vfs self.sjoin = self.store.join self.vfs.createmode = self.store.createmode + if (self.ui.configbool('devel', 'all-warnings') or + self.ui.configbool('devel', 'check-locks')): + if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs + self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit) + else: # standard vfs + self.svfs.audit = self._getsvfsward(self.svfs.audit) self._applyopenerreqs() if create: self._writerequirements() @@ -496,6 +502,25 @@ return ret return checkvfs + def _getsvfsward(self, origfunc): + """build a ward for self.svfs""" + rref = weakref.ref(self) + def checksvfs(path, mode=None): + ret = origfunc(path, mode=mode) + repo = rref() + if repo is None or not util.safehasattr(repo, '_lockref'): + return + if mode in (None, 'r', 'rb'): + return + if path.startswith(repo.sharedpath): + # truncate name relative to the repository (.hg) + path = path[len(repo.sharedpath) + 1:] + if repo._currentlock(repo._lockref) is None: + repo.ui.develwarn('write with no lock: "%s"' % path, + stacklevel=3) + return ret + return checksvfs + def close(self): self._writecaches()
--- a/tests/test-devel-warnings.t Tue Jul 11 12:38:17 2017 +0200 +++ b/tests/test-devel-warnings.t Mon Aug 08 18:14:42 2016 +0200 @@ -49,6 +49,11 @@ > with repo.vfs(b'branch', 'a'): > pass > + > @command(b'no-lock-write', [], '') + > def nolockwrite(ui, repo): + > with repo.svfs(b'fncache', 'a'): + > pass + > > @command(b'stripintr', [], '') > def stripintr(ui, repo): > lo = repo.lock() @@ -114,6 +119,9 @@ $ hg no-wlock-write devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* (nowlockwrite) (glob) + $ hg no-lock-write + devel-warn: write with no lock: "fncache" at: $TESTTMP/buggylocking.py:* (nolockwrite) (glob) + Stripping from a transaction $ echo a > a