summaryrefslogtreecommitdiff
path: root/java/src
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2009-12-04 06:51:23 +0100
committerJose <jose@zeroc.com>2009-12-04 06:51:23 +0100
commit0ad40835182795b5f9bedeea10aeb6f07c666e7d (patch)
tree5dff55b02aefb5854a972eb2cef128d1537d5c47 /java/src
parentBug 4408 - plugin does not work with x64 only installation (diff)
downloadice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.tar.bz2
ice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.tar.xz
ice-0ad40835182795b5f9bedeea10aeb6f07c666e7d.zip
4089 - IceGrid database corruption.
Diffstat (limited to 'java/src')
-rw-r--r--java/src/Freeze/SharedDbEnv.java15
-rw-r--r--java/src/IceUtil/FileLockException.java53
-rw-r--r--java/src/IceUtilInternal/FileLock.java135
3 files changed, 201 insertions, 2 deletions
diff --git a/java/src/Freeze/SharedDbEnv.java b/java/src/Freeze/SharedDbEnv.java
index b39088ec48f..e9747b1894b 100644
--- a/java/src/Freeze/SharedDbEnv.java
+++ b/java/src/Freeze/SharedDbEnv.java
@@ -271,6 +271,9 @@ public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
Ice.Properties properties = key.communicator.getProperties();
_trace = properties.getPropertyAsInt("Freeze.Trace.DbEnv");
+ String propertyPrefix = "Freeze.DbEnv." + _key.envName;
+ String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName);
+ _fileLock = new IceUtilInternal.FileLock(dbHome + "/Freeze.lock");
try
{
if(_ownDbEnv)
@@ -289,7 +292,6 @@ public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
//
config.setLockDetectMode(com.sleepycat.db.LockDetectMode.YOUNGEST);
- String propertyPrefix = "Freeze.DbEnv." + _key.envName;
if(properties.getPropertyAsInt(propertyPrefix + ".DbRecoverFatal") != 0)
{
config.setRunFatalRecovery(true);
@@ -317,7 +319,6 @@ public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
try
{
- String dbHome = properties.getPropertyWithDefault(propertyPrefix + ".DbHome", _key.envName);
java.io.File home = new java.io.File(dbHome);
_dbEnv = new com.sleepycat.db.Environment(home, config);
}
@@ -465,6 +466,14 @@ public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
_dbEnv = null;
}
}
+
+ //
+ // Release the file lock
+ //
+ if(_fileLock != null)
+ {
+ _fileLock.release();
+ }
}
private static String
@@ -524,4 +533,6 @@ public class SharedDbEnv implements com.sleepycat.db.ErrorHandler, Runnable
private java.util.Map<String, MapDb> _sharedDbMap = new java.util.HashMap<String, MapDb>();
private static java.util.Map<MapKey, SharedDbEnv> _map = new java.util.HashMap<MapKey, SharedDbEnv>();
+
+ private IceUtilInternal.FileLock _fileLock;
}
diff --git a/java/src/IceUtil/FileLockException.java b/java/src/IceUtil/FileLockException.java
new file mode 100644
index 00000000000..edef0f5da76
--- /dev/null
+++ b/java/src/IceUtil/FileLockException.java
@@ -0,0 +1,53 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceUtil;
+
+public class FileLockException extends RuntimeException implements Cloneable
+{
+ public FileLockException(String path)
+ {
+ this.path = path;
+ }
+ public java.lang.Object clone()
+ {
+ java.lang.Object o = null;
+ try
+ {
+ o = super.clone();
+ }
+ catch(CloneNotSupportedException ex)
+ {
+ assert false; // Impossible
+ }
+ return o;
+ }
+
+ public String
+ ice_name()
+ {
+ return "IceUtil::FileLockException";
+ }
+
+ public String
+ toString()
+ {
+ java.io.StringWriter sw = new java.io.StringWriter();
+ java.io.PrintWriter pw = new java.io.PrintWriter(sw);
+ IceUtilInternal.OutputBase out = new IceUtilInternal.OutputBase(pw);
+ out.setUseTab(false);
+ out.print(getClass().getName());
+ out.inc();
+ IceInternal.ValueWriter.write(this, out);
+ pw.flush();
+ return sw.toString();
+ }
+
+ public String path;
+}
diff --git a/java/src/IceUtilInternal/FileLock.java b/java/src/IceUtilInternal/FileLock.java
new file mode 100644
index 00000000000..46f167ee986
--- /dev/null
+++ b/java/src/IceUtilInternal/FileLock.java
@@ -0,0 +1,135 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+package IceUtilInternal;
+
+import java.io.File;
+import java.io.RandomAccessFile;
+import java.io.FileWriter;
+import java.nio.channels.FileChannel;
+import java.nio.channels.OverlappingFileLockException;
+import java.lang.management.ManagementFactory;
+
+public final class FileLock
+{
+ //
+ // The constructor opens the given file (eventually creating it)
+ // and acquires a lock on the file or throws FileLockException if
+ // the file couldn't be locked.
+ //
+ // If the lock can be acquired, the Java VM name is written to the
+ // file.
+ //
+ public FileLock(String path)
+ {
+ _file = new File(path);
+
+ FileChannel channel;
+ try
+ {
+ _randFile = new RandomAccessFile(_file, "rw");
+ channel = _randFile.getChannel();
+ }
+ catch(java.io.FileNotFoundException e)
+ {
+ throw new IceUtil.FileLockException(path);
+ }
+
+ java.nio.channels.FileLock lock;
+ try
+ {
+ lock = channel.tryLock();
+ }
+ catch(Exception ex)
+ {
+ IceUtil.FileLockException fe = new IceUtil.FileLockException(path);
+ fe.initCause(ex);
+ throw fe;
+ }
+
+ if(lock == null)
+ {
+ throw new IceUtil.FileLockException(path);
+ }
+
+ //
+ // In Windows we don't write the process pid to the file, as is not posible
+ // to read the file from other process while it is locked here.
+ //
+ if(!System.getProperty("os.name").startsWith("Windows"))
+ {
+ try
+ {
+ //
+ // Java doesn't provide get pid operation. This code
+ // writes the Java VM name instead of the pid.
+ //
+ // The output is JVM dependent. With the Sun
+ // implementation it's `pid@hostname'
+ //
+ _randFile.writeUTF(ManagementFactory.getRuntimeMXBean().getName());
+
+ //
+ // Don't close _randFile here or the lock will be released. It is called
+ // during release see comments there.
+ //
+ }
+ catch(java.io.IOException ex)
+ {
+ release();
+ throw new IceUtil.FileLockException(path);
+ }
+ }
+ }
+
+ //
+ // Remove the lock if it is owned by the class instance.
+ //
+ public void release()
+ {
+ if(System.getProperty("os.name").startsWith("Windows"))
+ {
+ if(_randFile != null)
+ {
+ //
+ // In Windows we need to close the file handler before
+ // we try to delete the file. Note that the call to close
+ // also release the file lock.
+ //
+ try
+ {
+ _randFile.close();
+ }
+ catch(java.io.IOException ex)
+ {
+ }
+ _randFile = null;
+ }
+ }
+ //
+ // on UNIX the call to delete remove the file and that
+ // release the lock.
+ //
+ // In Windows the call to delete will success if at that point
+ // the file has not been opened by any process.
+ //
+ if(_file != null)
+ {
+ _file.delete();
+ _file = null;
+ }
+ }
+
+ //
+ // We need to keep these refrences to delete the lock file during release
+ //
+ private File _file;
+ private RandomAccessFile _randFile;
+
+}