📄 niolockfile.java
字号:
public static final long MAX_LOCK_REGION = Long.MAX_VALUE; /** * Generally, the largest lock region that can be specified for files on * network file systems. <p> * * From the java.nio.channels.FileLock API JavaDocs: <p> * * Some network filesystems do not implement file locks on regions * that extend past a certain position, often 2**30 or 2**31. * In general, great care should be taken when locking files that * reside on network filesystems. */ public static final long MAX_NFS_LOCK_REGION = (1L << 30); /** * The smallest lock region that still protects the area actually used to * record lock information. */ public static final long MIN_LOCK_REGION = LockFile.USED_REGION; /** * Whether POSIX mandatory file lock tagging is performed by default. <p> * * Under the default build, this is <tt>false</tt>, but custom * distributions are free to rebuild with a default <tt>true</tt> * value. <p> * * For <em>Windows</em> targets, distributions should build with this set * false. */ public static final boolean POSIX_MANDITORY_FILELOCK_DEFAULT = false; /** * System property that can be used to control whether POSIX mandatory * file lock tagging is performed. */ public static final String POSIX_MANDITORY_FILELOCK_PROPERTY = "hsqldb.lockfile.posix.manditory.filelock"; /** * Represents an OS-enforced lock region upon this object's lock file. */ private volatile FileLock fileLock; /** * Retrieves whether POSIX mandatory file lock tagging is performed. <p> * * The value is obtained in the following manner: <p> * * <ol> * <li>manditory is assigned <tt>POSIX_MANDITORY_FILELOCK_DEFAULT</tt> * <li>manditory is assigned <tt>"true".equalsIgnoreCase( * System.getProperty(POSIX_MANDITORY_FILELOCK_PROPERTY, * manditory ? "true" : "false")); * </tt>, inside a try-catch block, to silently ignore any security * exception. * </ol> * @return <tt>true</tt> if POSIX mandatory file lock tagging is performed */ public boolean isPosixManditoryFileLock() { boolean manditory = POSIX_MANDITORY_FILELOCK_DEFAULT; try { manditory = "true".equalsIgnoreCase( System.getProperty( POSIX_MANDITORY_FILELOCK_PROPERTY, manditory ? "true" : "false")); } catch (Exception e) {} return manditory; } /** * Does work toward ensuring that a {@link #fileLock FileLock} exists upon * this object's lock file. <p> * * <b>POST:</b><p> * * Upon exit, if a valid <tt>fileLock</tt> could not be aquired for any * reason, then a best effort has also been expended toward releasing and * nullifying any resources obtained in the process. * * @return true if there is valid FileLock on exit, else false. */ protected boolean doOptionalLockActions() { // override return this.aquireFileLock(); } /** * Peforms best effort work toward releasing this object's * {@link #fileLock FileLock}, nullifying it in the process. * * @return true if <tt>fileLock</tt> is released successfully, else false */ protected boolean doOptionalReleaseActions() { // override return this.releaseFileLock(); } /** * Retrieves whether this object's {@link #fileLock FileLock} * represents a valid lock region upon this object's lock file. * * @return true if this object's {@link #fileLock FileLock} attribute is * valid, else false * @throws SecurityException if a required system property value cannot * be accessed, or if a security manager exists and its <tt>{@link * java.lang.SecurityManager#checkRead}</tt> method denies * read access to the lock file; */ public boolean isValid() { // override try { return super.isValid() && (this.fileLock != null && this.fileLock.isValid()); } catch (Exception e) { return false; } } /** * Retrieves the String value: "fileLock = " + {@link #fileLock FileLock}.<p> * * @return the String value: "fileLock = " + fileLock */ protected String toStringImpl() { // override return "fileLock = " + this.fileLock; } // ------------------------- Internal Implementation------------------------ // does the real work of aquiring the FileLock private boolean aquireFileLock() { // PRE: // // raf is never null and is never closed upon entry. // // Rhetorical question to self: How does one tell if a RandomAccessFile // is closed, short of invoking an operation and getting an IOException // the says its closed (assuming you can control the Locale of the error // message)? // final RandomAccessFile lraf = super.raf; // In an ideal world, we would use a lock region back off approach, // starting with region MAX_LOCK_REGION, then MAX_NFS_LOCK_REGION, // then MIN_LOCK_REGION. // // In practice, however, it is just generally unwise to mount network // file system database instances. Be warned. // // In general, it is probably also unwise to mount removable media // database instances that are not read-only. boolean success = false; try { if (this.fileLock != null) { // API says never throws exception, but I suspect // it's quite possible some research / FOSS JVMs might // still throw unsupported operation exceptions on certain // NIO classes...better to be safe than sorry. if (this.fileLock.isValid()) { return true; } else { // It's not valid, so releasing it is a no-op. // // However, we should still clean up the referenceand hope // no previous complications exist (a hung FileLock in a // flaky JVM) or that gc kicks in and saves the day... // (unlikely, though). this.releaseFileLock(); } } if (isPosixManditoryFileLock()) { try { Runtime.getRuntime().exec(new String[] { "chmod", "g+s,g-x", file.getPath() }); } catch (Exception ex) { //ex.printStackTrace(); } } // Note: from FileChannel.tryLock(...) JavaDoc: // // @return A lock object representing the newly-acquired lock, // or <tt>null</tt> if the lock could not be acquired // because another program holds an overlapping lock this.fileLock = lraf.getChannel().tryLock(0, MIN_LOCK_REGION, false); // According to the API, if it's non-null, it must be valid. // This may not actually yet be the full truth of the matter under // all commonly available JVM implementations. // fileLock.isValid() API says it never throws, though, so // with fingers crossed... success = (this.fileLock != null && this.fileLock.isValid()); } catch (Exception e) {} if (!success) { this.releaseFileLock(); } return success; } // does the real work of releasing the FileLock private boolean releaseFileLock() { // Note: Closing the super class RandomAccessFile has the // side-effect of closing the file lock's FileChannel, // so we do not deal with this here. boolean success = false; if (this.fileLock == null) { success = true; } else { try { this.fileLock.release(); success = true; } catch (Exception e) {} finally { this.fileLock = null; } } return success; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -