##// END OF EJS Templates
repovfs: add a ward to check if locks are properly taken...
Boris Feld -
r33436:9bb4decd default
parent child Browse files
Show More
@@ -234,6 +234,7 b' def reposetup(ui, repo):'
234 234
235 235 if util.safehasattr(ui, 'setrepo'):
236 236 ui.setrepo(repo)
237 repo._wlockfreeprefix.add('blackbox.log')
237 238
238 239 @command('^blackbox',
239 240 [('l', 'limit', 10, _('the number of events to show')),
@@ -69,6 +69,7 b' def extsetup(ui):'
69 69 def reposetup(ui, repo):
70 70 if repo.local():
71 71 repo.journal = journalstorage(repo)
72 repo._wlockfreeprefix.add('namejournal')
72 73
73 74 dirstate, cached = localrepo.isfilecached(repo, 'dirstate')
74 75 if cached:
@@ -122,6 +122,10 b' def uisetup(ui):'
122 122 cmdutil.extraexport.append('pullurl')
123 123 cmdutil.extraexportmap['pullurl'] = _addpullheader
124 124
125 def reposetup(ui, repo):
126 if not repo.local():
127 return
128 repo._wlockfreeprefix.add('last-email.txt')
125 129
126 130 def prompt(ui, prompt, default=None, rest=':'):
127 131 if default:
@@ -300,6 +300,26 b' class localrepository(object):'
300 300 # only functions defined in module of enabled extensions are invoked
301 301 featuresetupfuncs = set()
302 302
303 # list of prefix for file which can be written without 'wlock'
304 # Extensions should extend this list when needed
305 _wlockfreeprefix = {
306 # We migh consider requiring 'wlock' for the next
307 # two, but pretty much all the existing code assume
308 # wlock is not needed so we keep them excluded for
309 # now.
310 'hgrc',
311 'requires',
312 # XXX cache is a complicatged business someone
313 # should investigate this in depth at some point
314 'cache/',
315 # XXX shouldn't be dirstate covered by the wlock?
316 'dirstate',
317 # XXX bisect was still a bit too messy at the time
318 # this changeset was introduced. Someone should fix
319 # the remainig bit and drop this line
320 'bisect.state',
321 }
322
303 323 def __init__(self, baseui, path, create=False):
304 324 self.requirements = set()
305 325 self.filtername = None
@@ -319,10 +339,13 b' class localrepository(object):'
319 339 self.auditor = pathutil.pathauditor(self.root, self._checknested)
320 340 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested,
321 341 realfs=False)
322 self.vfs = vfsmod.vfs(self.path)
323 342 self.baseui = baseui
324 343 self.ui = baseui.copy()
325 344 self.ui.copy = baseui.copy # prevent copying repo configuration
345 self.vfs = vfsmod.vfs(self.path)
346 if (self.ui.configbool('devel', 'all-warnings') or
347 self.ui.configbool('devel', 'check-locks')):
348 self.vfs.audit = self._getvfsward(self.vfs.audit)
326 349 # A list of callback to shape the phase if no data were found.
327 350 # Callback are in the form: func(repo, roots) --> processed root.
328 351 # This list it to be filled by extension during repo setup
@@ -441,6 +464,38 b' class localrepository(object):'
441 464 # Signature to cached matcher instance.
442 465 self._sparsematchercache = {}
443 466
467 def _getvfsward(self, origfunc):
468 """build a ward for self.vfs"""
469 rref = weakref.ref(self)
470 def checkvfs(path, mode=None):
471 ret = origfunc(path, mode=mode)
472 repo = rref()
473 if (repo is None
474 or not util.safehasattr(repo, '_wlockref')
475 or not util.safehasattr(repo, '_lockref')):
476 return
477 if mode in (None, 'r', 'rb'):
478 return
479 if path.startswith(repo.path):
480 # truncate name relative to the repository (.hg)
481 path = path[len(repo.path) + 1:]
482 if path.startswith('journal.'):
483 # journal is covered by 'lock'
484 if repo._currentlock(repo._lockref) is None:
485 repo.ui.develwarn('write with no lock: "%s"' % path,
486 stacklevel=2)
487 elif repo._currentlock(repo._wlockref) is None:
488 # rest of vfs files are covered by 'wlock'
489 #
490 # exclude special files
491 for prefix in self._wlockfreeprefix:
492 if path.startswith(prefix):
493 return
494 repo.ui.develwarn('write with no wlock: "%s"' % path,
495 stacklevel=2)
496 return ret
497 return checkvfs
498
444 499 def close(self):
445 500 self._writecaches()
446 501
@@ -44,6 +44,11 b''
44 44 > wl.release()
45 45 > lo.release()
46 46 >
47 > @command(b'no-wlock-write', [], '')
48 > def nowlockwrite(ui, repo):
49 > with repo.vfs(b'branch', 'a'):
50 > pass
51 >
47 52 > @command(b'stripintr', [], '')
48 53 > def stripintr(ui, repo):
49 54 > lo = repo.lock()
@@ -104,6 +109,11 b''
104 109 $ hg properlocking
105 110 $ hg nowaitlocking
106 111
112 Writing without lock
113
114 $ hg no-wlock-write
115 devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* (nowlockwrite) (glob)
116
107 117 Stripping from a transaction
108 118
109 119 $ echo a > a
General Comments 0
You need to be logged in to leave comments. Login now