# HG changeset patch # User Vadim Gelfer # Date 1143565267 28800 # Node ID ff5c9a92f5566755aa06ee98d7622d5df6d90163 # Parent 182f500805dbb894fb536b279aed9bd7be6a817f fix backtrace printed when cannot get lock. change lock error handling code so exceptions have useful info and exception handling in one place. add test case for when cannot get lock. diff -r 182f500805db -r ff5c9a92f556 mercurial/commands.py --- a/mercurial/commands.py Sun Mar 26 22:54:05 2006 +0200 +++ b/mercurial/commands.py Tue Mar 28 09:01:07 2006 -0800 @@ -1244,12 +1244,8 @@ should properly record copied files, this information is not yet fully used by merge, nor fully reported by log. """ - try: - wlock = repo.wlock(0) - errs, copied = docopy(ui, repo, pats, opts, wlock) - except lock.LockHeld, inst: - ui.warn(_("repository lock held by %s\n") % inst.args[0]) - errs = 1 + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) return errs def debugancestor(ui, index, rev1, rev2): @@ -2256,18 +2252,14 @@ should properly record rename files, this information is not yet fully used by merge, nor fully reported by log. """ - try: - wlock = repo.wlock(0) - errs, copied = docopy(ui, repo, pats, opts, wlock) - names = [] - for abs, rel, exact in copied: - if ui.verbose or not exact: - ui.status(_('removing %s\n') % rel) - names.append(abs) - repo.remove(names, True, wlock) - except lock.LockHeld, inst: - ui.warn(_("repository lock held by %s\n") % inst.args[0]) - errs = 1 + wlock = repo.wlock(0) + errs, copied = docopy(ui, repo, pats, opts, wlock) + names = [] + for abs, rel, exact in copied: + if ui.verbose or not exact: + ui.status(_('removing %s\n') % rel) + names.append(abs) + repo.remove(names, True, wlock) return errs def revert(ui, repo, *pats, **opts): @@ -3252,6 +3244,15 @@ sys.exit(1) except hg.RepoError, inst: u.warn(_("abort: "), inst, "!\n") + except lock.LockHeld, inst: + if inst.errno == errno.ETIMEDOUT: + reason = _('timed out waiting for lock held by %s') % inst.locker + else: + reason = _('lock held by %s') % inst.locker + u.warn(_("abort: %s: %s\n") % (inst.desc or inst.filename, reason)) + except lock.LockUnavailable, inst: + u.warn(_("abort: could not lock %s: %s\n") % + (inst.desc or inst.filename, inst.strerror)) except revlog.RevlogError, inst: u.warn(_("abort: "), inst, "!\n") except SignalInterrupt: diff -r 182f500805db -r ff5c9a92f556 mercurial/localrepo.py --- a/mercurial/localrepo.py Sun Mar 26 22:54:05 2006 +0200 +++ b/mercurial/localrepo.py Tue Mar 28 09:01:07 2006 -0800 @@ -31,6 +31,7 @@ raise repo.RepoError(_("repository %s not found") % path) self.root = os.path.abspath(path) + self.origroot = path self.ui = ui.ui(parentui=parentui) self.opener = util.opener(self.path) self.wopener = util.opener(self.root) @@ -261,32 +262,31 @@ self.tagscache = None self.nodetagscache = None - def do_lock(self, lockname, wait, releasefn=None, acquirefn=None): + def do_lock(self, lockname, wait, releasefn=None, acquirefn=None, + desc=None): try: - l = lock.lock(self.join(lockname), 0, releasefn) + l = lock.lock(self.join(lockname), 0, releasefn, desc=desc) except lock.LockHeld, inst: if not wait: - raise inst - self.ui.warn(_("waiting for lock held by %s\n") % inst.args[0]) - try: - # default to 600 seconds timeout - l = lock.lock(self.join(lockname), - int(self.ui.config("ui", "timeout") or 600), - releasefn) - except lock.LockHeld, inst: - raise util.Abort(_("timeout while waiting for " - "lock held by %s") % inst.args[0]) + raise + self.ui.warn(_("waiting for lock on %s held by %s\n") % + (desc, inst.args[0])) + # default to 600 seconds timeout + l = lock.lock(self.join(lockname), + int(self.ui.config("ui", "timeout") or 600), + releasefn, desc=desc) if acquirefn: acquirefn() return l def lock(self, wait=1): - return self.do_lock("lock", wait, acquirefn=self.reload) + return self.do_lock("lock", wait, acquirefn=self.reload, + desc=_('repository %s') % self.origroot) def wlock(self, wait=1): - return self.do_lock("wlock", wait, - self.dirstate.write, - self.wreload) + return self.do_lock("wlock", wait, self.dirstate.write, + self.wreload, + desc=_('working directory of %s') % self.origroot) def checkfilemerge(self, filename, text, filelog, manifest1, manifest2): "determine whether a new filenode is needed" diff -r 182f500805db -r ff5c9a92f556 mercurial/lock.py --- a/mercurial/lock.py Sun Mar 26 22:54:05 2006 +0200 +++ b/mercurial/lock.py Tue Mar 28 09:01:07 2006 -0800 @@ -8,10 +8,16 @@ from demandload import * demandload(globals(), 'errno os socket time util') -class LockException(Exception): - pass +class LockException(IOError): + def __init__(self, errno, strerror, filename, desc): + IOError.__init__(self, errno, strerror, filename) + self.desc = desc + class LockHeld(LockException): - pass + def __init__(self, errno, filename, desc, locker): + LockException.__init__(self, errno, 'Lock held', filename, desc) + self.locker = locker + class LockUnavailable(LockException): pass @@ -24,7 +30,7 @@ # old-style lock: symlink to pid # new-style lock: symlink to hostname:pid - def __init__(self, file, timeout=-1, releasefn=None): + def __init__(self, file, timeout=-1, releasefn=None, desc=None): self.f = file self.held = 0 self.timeout = timeout @@ -32,6 +38,7 @@ self.id = None self.host = None self.pid = None + self.desc = desc self.lock() def __del__(self): @@ -49,7 +56,8 @@ if timeout > 0: timeout -= 1 continue - raise inst + raise LockHeld(errno.ETIMEDOUT, inst.filename, self.desc, + inst.locker) def trylock(self): if self.id is None: @@ -64,9 +72,11 @@ if why.errno == errno.EEXIST: locker = self.testlock() if locker: - raise LockHeld(locker) + raise LockHeld(errno.EAGAIN, self.f, self.desc, + locker) else: - raise LockUnavailable(why) + raise LockUnavailable(why.errno, why.strerror, + why.filename, self.desc) def testlock(self): '''return id of locker if lock is valid, else None.''' diff -r 182f500805db -r ff5c9a92f556 tests/test-lock-badness --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-lock-badness Tue Mar 28 09:01:07 2006 -0800 @@ -0,0 +1,11 @@ +#!/bin/sh + +hg init a +echo a > a/a +hg --cwd a ci -A -m a +hg clone a b +echo b > b/b +hg --cwd b ci -A -m b +chmod 100 a/.hg +hg --cwd b push ../a +chmod 700 a/.hg diff -r 182f500805db -r ff5c9a92f556 tests/test-lock-badness.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-lock-badness.out Tue Mar 28 09:01:07 2006 -0800 @@ -0,0 +1,4 @@ +adding a +adding b +pushing to ../a +abort: could not lock repository ../a: Permission denied