示例#1
0
def _AttemptPseudoLockRelease(pseudo_lock_fd):
    """Try to release the pseudo lock and return a boolean indicating whether
  the release was succesful.

  This whole operation is guarded with the global cloud storage lock, which
  prevents race conditions that might otherwise cause multiple processes to
  believe they hold the same pseudo lock (see _FileLock for more details).
  """
    pseudo_lock_path = pseudo_lock_fd.name
    try:
        with open(_CLOUD_STORAGE_GLOBAL_LOCK) as global_file:
            with lock.FileLock(global_file, lock.LOCK_EX | lock.LOCK_NB):
                lock.ReleaseFileLock(pseudo_lock_fd)
                pseudo_lock_fd.close()
                try:
                    os.remove(pseudo_lock_path)
                except OSError:
                    # We don't care if the pseudo lock gets removed elsewhere before
                    # we have a chance to do so.
                    pass
                return True
    except (lock.LockException, IOError):
        # We failed to acquire the global cloud storage lock and are thus unable to
        # release the pseudo lock.
        return False
def _FileLock(base_path):
    pseudo_lock_path = '%s.pseudo_lock' % base_path
    _CreateDirectoryIfNecessary(os.path.dirname(pseudo_lock_path))

    # We need to make sure that there is no other process which is acquiring the
    # lock on |base_path| and has not finished before proceeding further to create
    # the |pseudo_lock_path|. Otherwise, |pseudo_lock_path| may be deleted by
    # that other process after we create it in this process.
    while os.path.exists(pseudo_lock_path):
        time.sleep(0.1)

    # Guard the creation & acquiring lock of |pseudo_lock_path| by the global lock
    # to make sure that there is no race condition on creating the file.
    with open(_CLOUD_STORAGE_GLOBAL_LOCK) as global_file:
        with lock.FileLock(global_file, lock.LOCK_EX):
            fd = open(pseudo_lock_path, 'w')
            lock.AcquireFileLock(fd, lock.LOCK_EX)
    try:
        yield
    finally:
        lock.ReleaseFileLock(fd)
        try:
            fd.close()
            os.remove(pseudo_lock_path)
        except OSError:
            # We don't care if the pseudo-lock gets removed elsewhere before we have
            # a chance to do so.
            pass
示例#3
0
 def testUnlockBeforeClosingFile(self):
     tf = tempfile.NamedTemporaryFile(delete=False)
     tf.close()
     temp_status_file = tf.name
     try:
         with open(self.temp_file_path, 'r') as f:
             lock.AcquireFileLock(f, lock.LOCK_SH)
             lock.ReleaseFileLock(f)
             p = multiprocessing.Process(
                 target=_ReadFileWithExclusiveLockNonBlocking,
                 args=(self.temp_file_path, temp_status_file))
             p.start()
             p.join()
         with open(temp_status_file, 'r') as f:
             self.assertEquals('LockException was not raised', f.read())
     finally:
         os.remove(temp_status_file)