📄 lockfile.java
字号:
* This method should return <tt>false</tt> if optional locking work is not * performed or if it fails, else <tt>true</tt>. <p> * * In general, if optional locking work fails, then any resources * acquired in the process should be freed before this method returns. * In this way, the surrounding implementation can take advantage of a * <tt>false</tt> return value to avoid calling {@link * #doOptionalReleaseActions() doOptionalReleaseActions()} as part of the * {@link #tryRelease() tryRelease()} method. <p> * * <b>Note:</b><p> * * The default implementation does nothing and always returns * <tt>false</tt>. <p> * * @return <tt>true</tt> if optional lock actions are performed and they * succeed, else <tt>false</tt> */ protected boolean doOptionalLockActions() { return false; } /** * Provides any optional release actions for the {@link #tryRelease() * tryRelease()} template method. <p> * * <b>PRE:</b> <p> * * It is important that this method does not rethrow any exceptions * it encounters as unchecked exceptions to the calling context. <p> * * <b>POST:</b> <p> * * In general, <tt>false</tt> should be returned if optional locking work * is not performed or if it fails, else <tt>true</tt>. However, the return * value is currenly treated as purely informative. <p> * * <b>Note:</b> <p> * * The default implementation does nothing and always returns false. <p> * * @return <tt>true</tt> if optional release actions are performed and they * succeed, else <tt>false</tt> */ protected boolean doOptionalReleaseActions() { return false; } /** * Initializes this object with a <tt>File</tt> object whose path has the * canonical form of the given <tt>path</tt> argument. <p> * * <b>PRE</b>:<p> * * <ol> * <li>This method is called once and <em>only</em> once per * <tt>Lockfile</tt> instance. * * <li>It is <em>always</em> the first method called after * <tt>LockFile</tt> construction * * <li>The supplied <tt>path</tt> argument is <em>never</em> * <tt>null</tt>. * </ol> * * @param path the abstract path representing the file this object is to * use as its lock file * @throws FileCanonicalizationException if an I/O error occurs upon * canonicalization of the given path, which is possible because * the given path may be illegal on the runtime file system or * because construction of the canonical pathname may require * native file system queries * @throws FileSecurityException if a required system property value cannot * be accessed, or if a Java security manager exists and its * <tt>{@link java.lang.SecurityManager#checkRead}</tt> method denies * read access to the file; or if its <tt>{@link * java.lang.SecurityManager#checkRead(java.lang.String)}</tt> * method does not permit verification of the existence of * all necessary parent directories; or if * its <tt>{@link * java.lang.SecurityManager#checkWrite(java.lang.String)}</tt> * method does not permit all necessary parent directories to be * created */ private final void setPath(String path) throws LockFile.FileCanonicalizationException, LockFile.FileSecurityException { // Should at least be absolutized for reporting purposes, just in case // a security or canonicalization exception gets thrown. path = FileUtil.getDefaultInstance().canonicalOrAbsolutePath(path); this.file = new File(path); try { FileUtil.getDefaultInstance().makeParentDirectories(this.file); } catch (SecurityException ex) { throw new FileSecurityException(this, "setPath", ex); } try { this.file = FileUtil.getDefaultInstance().canonicalFile(path); } catch (SecurityException ex) { throw new FileSecurityException(this, "setPath", ex); } catch (IOException ex) { throw new FileCanonicalizationException(this, "setPath", ex); } this.cpath = this.file.getPath(); } /** * Opens (constructs) this object's {@link #raf RandomAccessFile}. <p> * * @throws UnexpectedFileNotFoundException if a * <tt>FileNotFoundException</tt> is thrown in reponse to * constructing the <tt>RandomAccessFile</tt> object. * @throws FileSecurityException if a required system property value cannot * be accessed, or if a Java security manager exists and its * <tt>{@link java.lang.SecurityManager#checkRead}</tt> method * denies read access to the file; or if its <tt>{@link * java.lang.SecurityManager#checkWrite(java.lang.String)}</tt> * method denies write access to the file */ private final void openRAF() throws LockFile.UnexpectedFileNotFoundException, LockFile.FileSecurityException { try { raf = new RandomAccessFile(file, "rw"); } catch (SecurityException ex) { throw new FileSecurityException(this, "openRAF", ex); } catch (FileNotFoundException ex) { throw new UnexpectedFileNotFoundException(this, "openRAF", ex); } catch (IOException ex) { throw new UnexpectedFileNotFoundException(this, "openRAF", ex); } } /** * Checks whether the given <tt>DataInputStream</tt> contains the * {@link #MAGIC} value. * * @param dis the stream to check * @throws FileSecurityException if a required system property value cannot * be accessed, or if a Java security manager exists and its * <tt>{@link java.lang.SecurityManager#checkRead}</tt> method * denies read access to the file * @throws UnexpectedEndOfFileException if an <tt>EOFException</tt> is * thrown while reading the <tt>DataInputStream</tt> * @throws UnexpectedFileIOException if an <tt>IOException</tt> other than * <tt>EOFException</tt> is thrown while reading the * <tt>DataInputStream</tt> * @throws WrongMagicException if a value other than <tt>MAGIC</tt> is read * from the <tt>DataInputStream</tt> */ private final void checkMagic(final DataInputStream dis) throws LockFile.FileSecurityException, LockFile.UnexpectedEndOfFileException, LockFile.UnexpectedFileIOException, LockFile.WrongMagicException { boolean success = true; final byte[] magic = new byte[MAGIC.length]; try { for (int i = 0; i < MAGIC.length; i++) { magic[i] = dis.readByte(); if (MAGIC[i] != magic[i]) { success = false; } } } catch (SecurityException ex) { throw new FileSecurityException(this, "checkMagic", ex); } catch (EOFException ex) { throw new UnexpectedEndOfFileException(this, "checkMagic", ex); } catch (IOException ex) { throw new UnexpectedFileIOException(this, "checkMagic", ex); } if (!success) { throw new WrongMagicException(this, "checkMagic", magic); } } /** * Retrieves the last written hearbeat timestamp from this object's lock * file. If this object's lock file does not exist, then <tt>Long.MIN_VALUE * </tt> (the earliest time representable as a <tt>long</tt> in Java) is * returned immediately. <p> * * @return the hearbeat timestamp read from this object's lock file, * as a <tt>long</tt> value or, if this object's lock * file does not exist, <tt>Long.MIN_VALUE</tt>, the earliest time * representable as a <tt>long</tt> in Java. * @throws FileSecurityException if a required system property value cannot * be accessed, or if a Java security manager exists and its * <tt>{@link java.lang.SecurityManager#checkRead}</tt> method * denies read access to the file * @throws UnexpectedEndOfFileException if an <tt>EOFException</tt> is * thrown while attempting to read the target file's <tt>MAGIC</tt> * or heartbeat timestamp value * @throws UnexpectedFileNotFoundException if, after successfully testing * for existence, the target file is not found a moment later while * attempting to read its <tt>MAGIC</tt> and heartbeat timestamp * values * @throws UnexpectedFileIOException if any other input stream error occurs * @throws WrongMagicException if the lock file does not start with the * the {@link #MAGIC} value */ private final long readHeartbeat() throws LockFile.FileSecurityException, LockFile.UnexpectedFileNotFoundException, LockFile.UnexpectedEndOfFileException, LockFile.UnexpectedFileIOException, LockFile.WrongMagicException { FileInputStream fis = null; DataInputStream dis = null; try { if (!file.exists()) { return Long.MIN_VALUE; } fis = new FileInputStream(file); dis = new DataInputStream(fis); checkMagic(dis); return dis.readLong(); } catch (SecurityException ex) { throw new FileSecurityException(this, "readHeartbeat", ex); } catch (FileNotFoundException ex) { throw new UnexpectedFileNotFoundException(this, "readHeartbeat", ex); } catch (EOFException ex) { throw new UnexpectedEndOfFileException(this, "readHeartbeat", ex); } catch (IOException ex) { throw new UnexpectedFileIOException(this, "readHeartbeat", ex); } finally { if (fis != null) { try { fis.close(); } catch (IOException ioe) { // ioe.printStackTrace(); } } } } /** * Schedules the lock heartbeat task. */ private final void startHeartbeat() { if (timerTask == null || HsqlTimer.isCancelled(timerTask)) { Runnable runner = new HeartbeatRunner(); timerTask = timer.schedulePeriodicallyAfter(0, HEARTBEAT_INTERVAL, runner, true); } } /** * Cancels the lock heartbeat task. */ private final void stopHeartbeat() { if (timerTask != null && !HsqlTimer.isCancelled(timerTask)) { HsqlTimer.cancel(timerTask); timerTask = null; } } /** * Writes the {@link #MAGIC} value to this object's lock file that * distiguishes it as an HSQLDB lock file. <p> * * @throws FileSecurityException possibly never (seek and write are native * methods whose JavaDoc entries do not actually specify throwing * <tt>SecurityException</tt>). However, it is conceivable that these * native methods may, in turn, access Java methods that do * throw <tt>SecurityException</tt>. In this case, a * <tt>SecurityException</tt> might be thrown if a required system * property value cannot be accessed, or if a security manager exists * and its <tt>{@link * java.lang.SecurityManager#checkWrite(java.io.FileDescriptor)}</tt> * method denies write access to the file * @throws UnexpectedEndOfFileException if an end of file exception is * thrown while attempting to write the <tt>MAGIC</tt> value to the * target file (typically, this cannot happen, but the case is * included to distiguish it from the general <tt>IOException</tt> * case). * @throws UnexpectedFileIOException if any other I/O error occurs while * attepting to write the <tt>MAGIC</tt> value to the target file. */ private final void writeMagic() throws LockFile.FileSecurityException, LockFile.UnexpectedEndOfFileException, LockFile.UnexpectedFileIOException { try { raf.seek(0); raf.write(MAGIC); } catch (SecurityException ex) { throw new FileSecurityException(this, "writeMagic", ex); } catch (EOFException ex) { throw new UnexpectedEndOfFileException(this, "writeMagic", ex); } catch (IOException ex) { throw new UnexpectedFileIOException(this, "writeMagic", ex); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -