blob: 53d3d43ceea731f5299fa2ab908c68ae094284b3 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.apache.ignite.testframework;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
/**
* OS-level file lock implementation.
*/
public class GridFileLock {
/** FS file for lock. */
private final File file;
/** Random access file for FS file. */
private final RandomAccessFile raFile;
/** File lock. */
private FileLock fileLock;
/**
* Initializes the lock.
*
* The constructor opens the lock file, which then should be
* closed with {@link #close()} method.
*
* @param file FS file to use as a lock file.
* @throws FileNotFoundException If error occurs on opening or creating the file.
*/
GridFileLock(File file) throws FileNotFoundException {
this.file = file;
raFile = new RandomAccessFile(file, "rw");
}
/**
* Performs an exclusive lock on a file, that
* this lock instance was constructed with.
*
* @throws IgniteCheckedException If failed to perform locking. The file remains open.
*/
public void lock() throws IgniteCheckedException {
lock(false);
}
/**
* Performs a lock (shared or exclusive) on a file, that
* this lock instance was constructed with.
*
* @param shared Whether a lock is shared (non-exclusive).
* @throws IgniteCheckedException If failed to perform locking. The file remains open.
*/
public void lock(boolean shared) throws IgniteCheckedException {
if (fileLock != null)
throw new IgniteCheckedException("Already locked [lockFile=" + file + ']');
try {
fileLock = raFile.getChannel().tryLock(0, Long.MAX_VALUE, shared);
if (fileLock == null)
throw new IgniteCheckedException("Failed to get exclusive lock on lock file [lockFile=" + file + ']');
}
catch (IOException | OverlappingFileLockException e) {
throw new IgniteCheckedException("Failed to get exclusive lock on lock file [lockFile=" + file + ']', e);
}
}
/**
* Unlocks the file.
*/
public void unlock() {
if (fileLock != null) {
U.releaseQuiet(fileLock);
fileLock = null;
}
}
/**
* Unlocks and closes the file.
*/
public void close() {
unlock();
U.closeQuiet(raFile);
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(GridFileLock.class, this);
}
}