|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.hsqldb.LockFile
The base HSQLDB cooperative file locking implementation and factory.
HEARTBEAT_INTERVAL
millisecond intervals,
acting as a heartbeat to indicate that a lock is still held.
File.deleteOnExit()
directive via
refelective method invocation (in order to stay JDK 1.1 compliant),
schedule a periodic heartbeat task and signify that the lock attempt
was successful, else...
HEARTBEAT_INTERVAL
milliseconds into the
past, assume that a lock condition is held by another process or a
database in an inaccessible class loader context and signify that the
lock attempt failed, else assume that the file is not in use, shedule
a periodic heartbeat task and signify that the lock attempt was
successful.
In addition to the generic lock and release rules, the protected methods
lockImpl()
and releaseImpl()
are called during lock and release attempts, respectively. This allows
transparent, JDK 1.1 compliant integration of extended strategies for
locking and releasing, based on subclassing and reflective construction
of such specializations in the factory method
newLockFile()
, determined by information gathered
at run-time.
In particular, if it is available at runtime, then newLockFile() retrieves
instances of NIOLockFile
to capitalize,
when possible, on the existence of the FileLock
class. If the NIOLockFile
class does not exist at
run-time or the java.nio classes it uses are not supported under the
run-time JVM, then newLockFile() produces vanilla LockFile instances,
meaning that only purely cooperative locking takes place, as opposed to
possibly O/S-enforced file locking which, at least in theory, is made
available through the java.nio.channels
package). However, it
must be noted that even if a JVM implementation provides the full
java.nio.channels package, it is not absolutely required to guarantee
that the underlying platform (the current operating system) provides
true process-wide file locking.
Note:
The NIOLockFile
descendent exists because it has been determined
though experimenatation that java.nio.channels.FileLock
does not always exhibit the correct/desired behaviour under reflective
method invocation. That is, it has been discovered that under some operating
system/JVM combinations, after calling FileLock.release()
via a reflective method invocation, the lock is not released properly,
deletion of the lock file is not possible even from the owning object
(this) and it is impossible for other LockFile
instances
or any other objects or processes to successfully obtain a lock
condition on the lock file, despite the fact that the FileLock
object reports that its lock is invalid (was released successfully).
Frustratingly, this condition appears to persist until full exit of the
JVM process in which the FileLock.tryLock()
method was
reflectively invoked.
To solve this, the original LockFile
class was split in two and
instead of reflective method invocation, reflection-based class
instantiation is now performed at the level of the newLockFile()
factory method. Similarly, the HSQLDB ANT build script detects the presence
or abscence of JDK 1.4 features such as java.nio and only attempts to build
and deploy NIOLockFile
to the hsqldb.jar if such features are
reported present.
Nested Class Summary | |
protected class |
LockFile.HeartbeatRunner
For internal use only. |
Field Summary | |
protected File |
f
Reference to this object's lock file. |
static long |
HEARTBEAT_INTERVAL
The period, in milliseconds, at which heartbeat timestamps are written to this object's lock file. |
protected boolean |
locked
Indicates whether this object has a lock condition on its lock file. |
static byte[] |
MAGIC
A magic value to place at the beginning of the lock file to differentiate it from other files. |
protected RandomAccessFile |
raf
A RandomAccessFile constructed from this object's reference, f, to its lock file. |
protected static HsqlTimer |
timer
The the timed shceduler with which to register this object's heartbeat task. |
Constructor Summary | |
LockFile()
|
Method Summary | |
boolean |
equals(Object obj)
Tests whether some other object is "equal to" this one. |
protected void |
finalize()
Attempts to release any lock condition this object may have on its lock file. |
String |
getCanonicalPath()
Retreives, as a String, the canonical path of this object's lock file. |
int |
hashCode()
Retrieves the hash code value for this object. |
boolean |
isLocked()
Retrieves whether this object has successfully obtained and is still currently holding (has not yet released) a cooperative lock condition on its lock file. |
static boolean |
isLocked(String path)
Retrieves whether there is potentially already a cooperative lock, operating system lock or some other situation preventing a cooperative lock condition from being aquired, relative to the specified path. |
boolean |
isValid()
Retrieves whether this object holds a valid lock on its lock file. |
protected boolean |
lockImpl()
Provides any specialized locking actions for the tryLock() method. |
static LockFile |
newLockFile(String path)
Retrieves a LockFile instance, initialized with a
File object whose path is the one specified by
the path argument. |
protected boolean |
releaseImpl()
Provides any specialized release actions for the tryRelease() method. |
String |
toString()
Retrieves a String representation of this object. |
protected String |
toStringImpl()
Retreives an implementation-specific tail value for the toString() method. |
protected void |
trace(Object o)
Prints tracing information and the value of the specified object |
boolean |
tryLock()
Attempts, if not already held, to obtain a cooperative lock condition on this object's lock file. |
boolean |
tryRelease()
Attempts to release any cooperative lock condition this object may have on its lock file. |
Methods inherited from class java.lang.Object |
clone, getClass, notify, notifyAll, wait, wait, wait |
Field Detail |
protected File f
protected RandomAccessFile raf
This RandomAccessFile is used to periodically write out the heartbeat timestamp to this object's lock file.
public static final long HEARTBEAT_INTERVAL
public static final byte[] MAGIC
protected boolean locked
protected static final HsqlTimer timer
Constructor Detail |
public LockFile()
Method Detail |
protected boolean lockImpl() throws Exception
tryLock()
method. Descendents are free to provide additional functionality here, using the following rules:
PRE:
This method is only called if tryLock() thinks it needs to get a lock
condition, so it can be assumed the locked == false upon entry, raf is
a non-null instance that can be used to get a FileChannel if desired,
and the lock file is, at the very least, readable. Further, this
object's heatbeat task is definitely cancelled and/or has not yet been
scheduled, so whatever timestamp is recorded in the lock file, if it
exists, is what was written by a previous locker, if any. A timestamp
value in a preexisting file is only considered valid if the file is
of the correct length and its first eight bytes are
the value MAGIC
.
POST:
This method must return false if any additional locking work fails,
else true.
The default implementation of this method reflectively (for JDK1.1
compliance) invokes f.deleteOnExit() in a silent manner and always
returns true.
true
if no extended locking
actions are taken or the actions succeed,
else false
.
Exception
- if a situation is encountered that absolutely
prevents the status of the lock condtion
to be determined. (e.g. an IO exception
occurs here)protected boolean releaseImpl() throws Exception
Exception
- if a situation is encountered that absolutely
prevents the status of the lock condtion
to be determined. (e.g. an IO exception
occurs here).public static LockFile newLockFile(String path) throws Exception
LockFile
instance, initialized with a
File
object whose path is the one specified by
the path
argument.
path
- the path of the File
object with
which the retrieved LockFile
object is to be initialized
LockFile
instance initialized with a
File
object whose path is the one specified
by the path
argument.
Exception
public boolean equals(Object obj)
LockFile
object iff it
is not null, it is an instance of LockFile
and either it's
the identical instance or it has the same lock file. More formally,
is is considered equal iff it is not null, it is an instance of
LockFile
, and the expression:
this == other || this.f == null ? other.f == null : this.f.equals(other.f);yeilds true.
obj
- the reference object with which to compare.
true
if this object is equal to
the obj
argument;
false
otherwise.hashCode()
public String getCanonicalPath()
public int hashCode()
File
object attribute
f
is null
, else it is the hashCode
of f
. That is, two LockFile
objects have the same hashCode
value if they have the
same lock file.
equals(java.lang.Object)
public boolean isLocked()
Note: Due to the retrictions placed on the JVM by platform-independence, it is very possible to successfully obtain and hold a cooperative lock on a lock file and yet for the lock to become invalid while held.
For instance, under JVMs with no java.nio
package or
operating systems that cannot live up to the contracts set forth for
FileLock
, it is quite possible
for another process or even an uncooperative bit of code running
in the same JVM to delete or overwrite the lock file while
this object holds a lock on it.
Because of this, the isValid() method is provided in the public interface in order to allow clients to detect such situations.
isValid()
public static boolean isLocked(String path)
path
- the path to testpublic boolean isValid()
More formally, this method retrieves true iff:
isLocked() && f != null && f.exists() && raf != null
public String toString()
The String is of the form:
super.toString() + "[file=" + getAbsolutePath() + ", exists=" + f.exists() + ", locked=" + isLocked() + ", valid=" + isValid() + ", " + toStringImpl() + "]";
toStringImpl()
protected String toStringImpl()
The default implementation returns the empty string.
toString()
public boolean tryLock() throws Exception
true
if this object already holds a lock or
the lock was obtained successfully, else
false
Exception
- if an error occurs that absolutely prevents the lock
status of the lock condition from being determined
(e.g. an unhandled file I/O error).public boolean tryRelease() throws Exception
true
if this object does not hold a
lock or the lock is released successfully,
else false
.
Exception
- if an error occurs that absolutely prevents
the status of the lock condition from
being determined (e.g. an unhandled file
I/O exception).protected void trace(Object o)
o
- the value to printprotected void finalize() throws Throwable
Throwable
- if this object encounters an unhandled exception
trying to release the lock condition,
if any, that it has on its lock file.
|
|||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |