81 lines
2.9 KiB
Java
81 lines
2.9 KiB
Java
package org.broadinstitute.sting.utils.threading;
|
|
|
|
import org.apache.log4j.Logger;
|
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
|
import org.broadinstitute.sting.utils.exceptions.UserException;
|
|
|
|
import java.io.File;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.RandomAccessFile;
|
|
import java.nio.channels.*;
|
|
|
|
/**
|
|
* User: depristo
|
|
* Date: 1/19/11
|
|
* Time: 8:24 AM
|
|
*
|
|
* A reentrant lock that supports multi-threaded locking as well as a shared file lock on a common
|
|
* file in the file system. It itself a shared memory reenterant lock to managed thread safety and
|
|
* contains a SharedFileLock to handle the file integrity.
|
|
*/
|
|
public class SharedFileThreadSafeLock extends ClosableReentrantLock {
|
|
private static Logger logger = Logger.getLogger(SharedFileThreadSafeLock.class);
|
|
protected static final boolean DEBUG = false;
|
|
|
|
private final SharedFileLock fileLock;
|
|
|
|
/**
|
|
* Create a SharedFileThreadSafeLock object locking the file
|
|
* @param file
|
|
*/
|
|
public SharedFileThreadSafeLock(File file, int nRetries, long milliSecPerTry, int ID) {
|
|
super();
|
|
this.fileLock = new SharedFileLock(file, nRetries, milliSecPerTry, ID);
|
|
}
|
|
|
|
public SharedFileThreadSafeLock(File file, int ID) {
|
|
this(file, SharedFileLock.DEFAULT_N_TRIES, SharedFileLock.DEFAULT_MILLISECONDS_PER_TRY, ID);
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
super.close();
|
|
fileLock.close();
|
|
}
|
|
|
|
@Override
|
|
public int getHoldCount() {
|
|
if ( super.getHoldCount() != fileLock.getHoldCount() )
|
|
throw new ReviewedStingException("BUG: unequal hold counts. threadlock = " + super.getHoldCount() + ", filelock = " + fileLock.getHoldCount());
|
|
return super.getHoldCount();
|
|
}
|
|
|
|
@Override
|
|
public boolean ownsLock() {
|
|
return super.isHeldByCurrentThread() && fileLock.ownsLock();
|
|
}
|
|
|
|
/**
|
|
* Two stage [threading then file] locking mechanism. Reenterant in that multiple lock calls will be
|
|
* unwound appropriately. Uses file channel lock *after* thread locking.
|
|
*/
|
|
@Override
|
|
public void lock() {
|
|
if ( DEBUG ) logger.warn("Attempting SharedFileThreadSafe lock: " + Thread.currentThread().getName());
|
|
if ( DEBUG ) logger.warn(" going for thread lock: " + Thread.currentThread().getName());
|
|
super.lock();
|
|
if ( DEBUG ) logger.warn(" going for file lock: " + Thread.currentThread().getName());
|
|
fileLock.lock(); // todo -- should this be in a try?
|
|
}
|
|
|
|
@Override
|
|
public void unlock() {
|
|
if ( DEBUG ) logger.warn(" releasing filelock: " + Thread.currentThread().getName());
|
|
fileLock.unlock();
|
|
if ( DEBUG ) logger.warn(" releasing threadlock: " + Thread.currentThread().getName());
|
|
super.unlock();
|
|
if ( DEBUG ) logger.warn(" unlock() complete: " + Thread.currentThread().getName());
|
|
}
|
|
}
|