def acquire(self): logger.debug("Acquiring lock %s" % self.lock_id) if not os.path.exists(self.path): self._make_lockfile() while True: with open(self.path, "r+") as f: fcntl.flock(f, fcntl.LOCK_EX) pid = _readpid(f) if pid==None: _writepid(f) fcntl.flock(f, fcntl.LOCK_UN) logger.debug("%d got lock %s" % (os.getpid(), self.lock_id)) return elif pid == os.getpid(): fcntl.flock(f, fcntl.LOCK_UN) raise LockError("Process %d attempting to acquire lock %s which it already holds" % (pid, self.lock_id)) elif not is_process_alive(pid): logger.debug("%d: Lock holder %d of lock %s is dead, taking lock for myself" % (os.getpid(), pid, self.lock_id)) _writepid(f) fcntl.flock(f, fcntl.LOCK_UN) return else: fcntl.flock(f, fcntl.LOCK_UN) time.sleep(TIMEOUT)
def acquire_if_available(self): """Attempt to get the lock. Returns (True, mypid) if the attempt was successful and (False, holder_pid) otherwise. """ logger.debug("Attepting to acquire lock %s" % self.lock_id) mypid = os.getpid() if not os.path.exists(self.path): self._make_lockfile() with open(self.path, "r+") as f: fcntl.flock(f, fcntl.LOCK_EX) pid = _readpid(f) if pid==None: _writepid(f) fcntl.flock(f, fcntl.LOCK_UN) logger.debug("%d got lock %s" % (mypid, self.lock_id)) return (True, mypid) elif pid == mypid: fcntl.flock(f, fcntl.LOCK_UN) raise LockError("Process %d attempting to acquire lock %s which it already holds" % (pid, self.lock_id)) elif not is_process_alive(pid): logger.debug("%d: Lock holder %d of lock %s is dead, taking lock for myself" % (mypid, pid, self.lock_id)) _writepid(f) fcntl.flock(f, fcntl.LOCK_UN) return (True, mypid) else: fcntl.flock(f, fcntl.LOCK_UN) return (False, pid)
def is_locked(self): if not os.path.exists(self.path): return False with open(self.path, "r") as f: fcntl.flock(f, fcntl.LOCK_EX) pid = _readpid(f) fcntl.flock(f, fcntl.LOCK_UN) if pid!=None and (pid==os.getpid() or is_process_alive(pid)): return True else: return False