def acquire(self, timeout=60): '''Locks the token cache for this key and username. If the token cache is already locked, waits until it is released. Throws an exception when the lock cannot be acquired after ``timeout`` seconds. ''' # Check whether there is a PID file already with our PID in # it. lockpid = self.get_lock_pid() if lockpid == os.getpid(): LOG.debug('The lock is ours, continuing') return # Figure out the lock filename lock = self.get_lock_name() LOG.debug('Acquiring lock %s' % lock) # Try to obtain the lock start_time = time.time() while True: try: os.makedirs(lock) break except OSError: # If the path doesn't exist, the error isn't that it # can't be created because someone else has got the # lock. Just bail out then. if not os.path.exists(lock): LOG.error('Unable to acquire lock %s, aborting' % lock) raise if time.time() - start_time >= timeout: # Timeout has passed, bail out raise LockingError('Unable to acquire lock ' + '%s, aborting' % lock) # Wait for a bit, then try again LOG.debug('Unable to acquire lock, waiting') time.sleep(0.1) # Write the PID file LOG.debug('Lock acquired, writing our PID') pidfile = open(self.pidfile_name, 'w') try: pidfile.write('%s' % os.getpid()) finally: pidfile.close()
def release(self): '''Unlocks the token cache for this key.''' # Figure out the lock filename lock = self.get_lock_name() if not os.path.exists(lock): LOG.warn('Trying to release non-existing lock %s' % lock) return # If the PID file isn't ours, abort. lockpid = self.get_lock_pid() if lockpid and lockpid != os.getpid(): raise LockingError(('Lock %s is NOT ours, but belongs ' + 'to PID %i, unable to release.') % (lock, lockpid)) LOG.debug('Releasing lock %s' % lock) # Remove the PID file and the lock directory pidfile = self.pidfile_name if os.path.exists(pidfile): os.remove(pidfile) os.removedirs(lock)