import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.channels.ReadableByteChannel;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
fileLock.release();// tidy up invalid lock
fileLock=null;
}
- if (extantlock!=null)
- fileLock=extantlock;
+ if (extantlock!=null && extantlock.isLocked())
+ fileLock=extantlock; // THIS IS BROKEN - lockFile then nulls the lock.
return lockFile();
}
-
- /**
- * Get a lock for the SessionFile
- *
- * @return true if lock was made
- */
- protected boolean lockFile() {
- if (fileLock != null)
- if (fileLock.isLocked())
- return true;
- else
- // lock failed for some reason.
- fileLock.release();
- fileLock = null;
+ private boolean ensureSessionFile() {
if (sessionFile != null) {
if (!sessionFile.exists()) {
// create new file
return false;
}
}
- // TODO: see if we need to loop-wait for locks or they just block until
- // lock is made...
- long tries=500;
- do {
- tries--;
- if (fileLock!=null && !fileLock.isLocked())
- fileLock.release();
- fileLock = new Lock(sessionFile); // TODO: wait around if we can't get the lock.
- } while (tries>0 && !fileLock.isLocked());
- if (!fileLock.isLocked())
- log.error("Failed to get lock for "+sessionFile);
- // fileLock = new Lock(sessionFile);
- return fileLock.isLocked();
- } else
- log.error("lockFile called for non-initialised SessionFile!");
-
- // no lock possible
+ return true;
+ }
+ log.error("ensureSessionFile called for non-initialised SessionFile!");
return false;
}
+ /**
+ * Get a lock for the SessionFile
+ *
+ * @return true if lock was made
+ */
+ protected boolean lockFile() {
+ if (fileLock != null) {
+ if (fileLock.isLocked()) {
+ if (!ensureSessionFile())
+ return false;
+ return true;
+ } else {
+ // lock failed for some reason.
+ fileLock.release();
+ log.info("Unexpected session file lock failure. Trying to get it again.");
+ fileLock=null;
+ }
+ }
+ if (!ensureSessionFile())
+ return false;
+ // TODO: see if we need to loop-wait for locks or they just block until
+ // lock is made...
+ long tries=5000;
+ do {
+ tries--;
+ if (fileLock==null || !fileLock.isLocked()) {
+ //try { Thread.sleep(1); } catch (Exception e) {};
+ fileLock = LockFactory.getLock(sessionFile,true); // TODO: wait around if we can't get the lock.
+ }
+ } while (tries>0 && !fileLock.isLocked());
+ if (!fileLock.isLocked())
+ log.error("Failed to get lock for "+sessionFile);
+ // fileLock = new Lock(sessionFile);
+ return fileLock.isLocked();
+ }
/**
* Explicitly release the SessionFile's lock.
if (lockFile(extantLock)) {
try {
tempfile = File.createTempFile(backupPrefix, backupSuffix, backupDir);
- FileOutputStream tos = new FileOutputStream(tempfile);
- tos.getChannel().transferFrom(fileLock.rafile.getChannel(), 0,
- fileLock.rafile.length());
- tos.close();
+ if (fileLock.length()>0) {
+ FileOutputStream tos = new FileOutputStream(tempfile);
+ ReadableByteChannel channel;
+ tos.getChannel().transferFrom(channel=fileLock.getRaChannel(), 0,
+ fileLock.length());
+ tos.close();
+ if (!channel.isOpen())
+ throw new Error(tos.getChannel().getClass()+".transferFrom closes source channel!");
+ if (!lockFile(extantLock))
+ throw new Error("Lost lock for "+sessionFile.getName()+" after backup.");
+
+ }
} catch (FileNotFoundException e1) {
log.warn("Can't create temp file for "+sessionFile.getName(),e1);
tempfile=null;
if (newData.sessionFile==null)
throw new IOException("Null SessionFile in newData.");
- lockFile(extantLock);
- newData.lockFile();
- fileLock.rafile.getChannel().transferFrom(newData.fileLock.rafile.getChannel(), 0,
- newData.fileLock.rafile.length());
+ if (!lockFile(extantLock))
+ throw new IOException("Failed to get write lock for "+sessionFile);
+ if (!newData.lockFile())
+ throw new IOException("Failed to get lock for updateFrom "+newData.sessionFile);
+ RandomAccessFile nrafile = newData.fileLock.getRaFile();
+ nrafile.seek(0);
+ RandomAccessFile trafile = fileLock.getRaFile();
+ /*long tries=5000;
+ while (trafile==null && --tries>0) {
+ log.debug("Lost lock on "+sessionFile+"! Re-trying for a transfer.");
+ lockFile();
+ trafile = fileLock.getRaFile();
+ }*/
+ trafile.seek(0);
+ trafile.getChannel().transferFrom(nrafile.getChannel(), 0,
+ nrafile.length());
}
/**
* remove all trace of the sessionFile file