All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.services.s3.internal.FileLocks Maven / Gradle / Ivy

Go to download

The AWS Java SDK for Amazon S3 module holds the client classes that are used for communicating with Amazon Simple Storage Service

There is a newer version: 1.12.778
Show newest version
/*
 * Copyright 2015-2024 Amazon Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *    http://aws.amazon.com/apache2.0
 *
 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and
 * limitations under the License.
 */
package com.amazonaws.services.s3.internal;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Map;
import java.util.TreeMap;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.amazonaws.annotation.ThreadSafe;

import com.amazonaws.services.s3.transfer.exception.FileLockException;
import com.amazonaws.util.IOUtils;

/**
 * An internal utility used to provide both inter and intra JVM file locking.
 * This works well as long as this class is loaded with the same class loader in
 * a JVM. Otherwise, intra-JVM file locking is not guaranteed.
 * 

* Per javadoc of {@link FileLock}, "File locks are held on behalf of the entire * Java virtual machine. They are not suitable for controlling access to a file * by multiple threads within the same virtual machine." *

* Hence the need for this utility class. */ @ThreadSafe public enum FileLocks { ; // External file lock doesn't seem to work correctly on Windows, // so disabling for now (Ref: TT0047889941) private static final boolean EXTERNAL_LOCK = false; private static final Log log = LogFactory.getLog(FileLocks.class); private static final Map lockedFiles = new TreeMap(); /** * Acquires an exclusive lock on the specified file, creating the file as * necessary. Caller of this method is responsible to call the * {@link #unlock(File)} method to prevent release leakage. * * @return true if the locking is successful; false otherwise. * * @throws FileLockException if we failed to lock the file */ public static boolean lock(File file) { synchronized(lockedFiles) { if (lockedFiles.containsKey(file)) return false; // already locked } FileLock lock = null; RandomAccessFile raf = null; try { // Note if the file does not already exist then an attempt will be // made to create it because of the use of "rw". raf = new RandomAccessFile(file, "rw"); FileChannel channel = raf.getChannel(); if (EXTERNAL_LOCK) lock = channel.lock(); } catch (Exception e) { IOUtils.closeQuietly(raf, log); throw new FileLockException(e); } final boolean locked; synchronized(lockedFiles) { RandomAccessFile prev = lockedFiles.put(file, raf); if (prev == null) { locked = true; } else { // race condition: some other thread got locked it before this locked = false; lockedFiles.put(file, prev); // put it back } } if (locked) { if (log.isDebugEnabled()) log.debug("Locked file " + file + " with " + lock); } else { IOUtils.closeQuietly(raf, log); } return locked; } /** * Returns true if the specified file is currently locked; false otherwise. */ public static boolean isFileLocked(File file) { synchronized(lockedFiles) { return lockedFiles.containsKey(file); } } /** * Unlocks a file previously locked via {@link #lock(File)}. * * @return true if the unlock is successful; false otherwise. Successful * unlock means we have found and attempted to close the locking * file channel, but ignoring the fact that the close operation may * have actually failed. */ public static boolean unlock(File file) { synchronized(lockedFiles) { final RandomAccessFile raf = lockedFiles.get(file); if (raf == null) return false; else { // Must close out the channel before removing it from the map; // or else risk giving a false negative (of no lock but in fact // the file is still locked by the file system.) IOUtils.closeQuietly(raf, log); lockedFiles.remove(file); } } if (log.isDebugEnabled()) log.debug("Unlocked file " + file); return true; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy