package backupclient.commons;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
public class CrossProcessLock {
public static CrossProcessLock instance = new CrossProcessLock();
private final File lock_file;
private final Object internal_lock = new Object();
private Thread local_holder;
private FileLock lock;
private CrossProcessLock() {
String tmp_dir = System.getProperty("java.io.tmpdir");
if (! (tmp_dir.endsWith("/")) || tmp_dir.endsWith("\\")) {
tmp_dir += System.getProperty("file.separator");
}
lock_file = new File(tmp_dir, "focusbackup.lock~");
System.out.println(lock_file);
}
static {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
instance.releaseLock();
}
});
}
// Will sleep one second after each try
public boolean tryLock(int max_tries) {
assert max_tries >= 0;
if (local_holder == Thread.currentThread()) return true;
else try {
int tries=0;
RandomAccessFile raf = new RandomAccessFile(lock_file, "rw");
FileChannel channel = raf.getChannel();
do {
synchronized (internal_lock) {
if (local_holder == null && (lock = channel.tryLock()) != null) {
local_holder = Thread.currentThread();
return true;
}
}
Thread.sleep(1000);
} while (++tries < max_tries);
} catch (Exception e) {
e.printStackTrace(); //
}
return false;
}
public synchronized void releaseLock() {
if (lock != null) {
try {
lock.release();
lock = null;
local_holder = null;
} catch (IOException e) {
e.printStackTrace(); // TODO use logger. Maybe make api handler singelton?
}
}
}
}