Mercurial > hg > mercurial-crew-with-dirclash
changeset 2016:ff5c9a92f556
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.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Tue, 28 Mar 2006 09:01:07 -0800 |
parents | 182f500805db |
children | 4c03bc02c779 |
files | mercurial/commands.py mercurial/localrepo.py mercurial/lock.py tests/test-lock-badness tests/test-lock-badness.out |
diffstat | 5 files changed, 67 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1244,12 +1244,8 @@ def copy(ui, repo, *pats, **opts): 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 @@ def rename(ui, repo, *pats, **opts): 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 @@ def dispatch(args): 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:
--- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -31,6 +31,7 @@ class localrepository(object): 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 @@ class localrepository(object): 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"
--- a/mercurial/lock.py +++ b/mercurial/lock.py @@ -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 @@ class lock(object): # 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 @@ class lock(object): self.id = None self.host = None self.pid = None + self.desc = desc self.lock() def __del__(self): @@ -49,7 +56,8 @@ class lock(object): 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 @@ class lock(object): 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.'''