diff --git a/builder.py b/builder.py index 15f435c..4cc0fc8 100644 --- a/builder.py +++ b/builder.py @@ -353,18 +353,18 @@ def main(targets, shouldbuildfunc): backoff *= 2 if vars.DEBUG_LOCKS: warn('%s (WAITING)\n' % _nice(t)) + try: + lock.check() + except state.CyclicDependencyError: + err('cyclic dependency while building %s\n' % _nice(t)) + retcode[0] = 208 + return retcode[0] # this sequence looks a little silly, but the idea is to # give up our personal token while we wait for the lock to # be released; but we should never run get_token() while # holding a lock, or we could cause deadlocks. jwack.release_mine() - try: - lock.waitlock() - except state.CyclicDependencyError: - err('cyclic dependency while building %s\n' % _nice(t)) - jwack.get_token(t) - retcode[0] = 208 - return retcode[0] + lock.waitlock() lock.unlock() jwack.get_token(t) lock.trylock() diff --git a/jwack.py b/jwack.py index 1242e60..80786b4 100644 --- a/jwack.py +++ b/jwack.py @@ -18,8 +18,8 @@ def _debug(s): def _release(n): global _mytokens - _debug('release(%d)\n' % n) _mytokens += n + _debug('release(%d) -> %d\n' % (n, _mytokens)) if _mytokens > 1: os.write(_fds[1], 't' * (_mytokens-1)) _mytokens = 1 @@ -28,8 +28,9 @@ def _release(n): def release_mine(): global _mytokens assert(_mytokens >= 1) - os.write(_fds[1], 't') _mytokens -= 1 + _debug('release_mine() -> %d\n' % _mytokens) + os.write(_fds[1], 't') def _timeout(sig, frame): @@ -198,7 +199,7 @@ def wait_all(): bb += b if not b: break if len(bb) != _toplevel-1: - raise Exception('on exit: expected %d tokens; found only %r' + raise Exception('on exit: expected %d tokens; found %r' % (_toplevel-1, len(bb))) os.write(_fds[1], bb) diff --git a/state.py b/state.py index c857ebf..d27f472 100644 --- a/state.py +++ b/state.py @@ -348,8 +348,14 @@ class Lock: if self.lockfile is not None: os.close(self.lockfile) - def trylock(self): + def check(self): assert(not self.owned) + if str(self.fid) in vars.get_locks(): + # Lock already held by parent: cyclic dependence + raise CyclicDependencyError() + + def trylock(self): + self.check() try: fcntl.lockf(self.lockfile, fcntl.LOCK_EX|fcntl.LOCK_NB, 0, 0) except IOError, e: @@ -361,10 +367,7 @@ class Lock: self.owned = True def waitlock(self): - assert(not self.owned) - if str(self.fid) in vars.get_locks(): - # Lock already held by parent: cyclic dependence - raise CyclicDependencyError() + self.check() fcntl.lockf(self.lockfile, fcntl.LOCK_EX, 0, 0) self.owned = True