1. /*
  2. * @(#)FileLock.java 1.8 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.nio.channels;
  8. import java.io.IOException;
  9. /**
  10. * A token representing a lock on a region of a file.
  11. *
  12. * <p> A file-lock object is created each time a lock is acquired on a file via
  13. * one of the {@link FileChannel#lock(long,long,boolean) lock} or {@link
  14. * FileChannel#tryLock(long,long,boolean) tryLock} methods of the {@link
  15. * FileChannel} class.
  16. *
  17. * <p> A file-lock object is initially valid. It remains valid until the lock
  18. * is released by invoking the {@link #release release} method, by closing the
  19. * channel that was used to acquire it, or by the termination of the Java
  20. * virtual machine, whichever comes first. The validity of a lock may be
  21. * tested by invoking its {@link #isValid isValid} method.
  22. *
  23. * <p> A file lock is either <i>exclusive</i> or <i>shared</i>. A shared lock
  24. * prevents other concurrently-running programs from acquiring an overlapping
  25. * exclusive lock, but does allow them to acquire overlapping shared locks. An
  26. * exclusive lock prevents other programs from acquiring an overlapping lock of
  27. * either type. Once it is released, a lock has no further effect on the locks
  28. * that may be acquired by other programs.
  29. *
  30. * <p> Whether a lock is exclusive or shared may be determined by invoking its
  31. * {@link #isShared isShared} method. Some platforms do not support shared
  32. * locks, in which case a request for a shared lock is automatically converted
  33. * into a request for an exclusive lock.
  34. *
  35. * <p> The locks held on a particular file by a single Java virtual machine do
  36. * not overlap. The {@link #overlaps overlaps} method may be used to test
  37. * whether a candidate lock range overlaps an existing lock.
  38. *
  39. * <p> A file-lock object records the file channel upon whose file the lock is
  40. * held, the type and validity of the lock, and the position and size of the
  41. * locked region. Only the validity of a lock is subject to change over time;
  42. * all other aspects of a lock's state are immutable.
  43. *
  44. * <p> File locks are held on behalf of the entire Java virtual machine.
  45. * They are not suitable for controlling access to a file by multiple
  46. * threads within the same virtual machine.
  47. *
  48. * <p> File-lock objects are safe for use by multiple concurrent threads.
  49. *
  50. *
  51. * <a name="pdep">
  52. * <h4> Platform dependencies </h4>
  53. *
  54. * <p> This file-locking API is intended to map directly to the native locking
  55. * facility of the underlying operating system. Thus the locks held on a file
  56. * should be visible to all programs that have access to the file, regardless
  57. * of the language in which those programs are written.
  58. *
  59. * <p> Whether or not a lock actually prevents another program from accessing
  60. * the content of the locked region is system-dependent and therefore
  61. * unspecified. The native file-locking facilities of some systems are merely
  62. * <i>advisory</i>, meaning that programs must cooperatively observe a known
  63. * locking protocol in order to guarantee data integrity. On other systems
  64. * native file locks are <i>mandatory</i>, meaning that if one program locks a
  65. * region of a file then other programs are actually prevented from accessing
  66. * that region in a way that would violate the lock. On yet other systems,
  67. * whether native file locks are advisory or mandatory is configurable on a
  68. * per-file basis. To ensure consistent and correct behavior across platforms,
  69. * it is strongly recommended that the locks provided by this API be used as if
  70. * they were advisory locks.
  71. *
  72. * <p> On some systems, acquiring a mandatory lock on a region of a file
  73. * prevents that region from being {@link java.nio.channels.FileChannel#map
  74. * </code>mapped into memory<code>}, and vice versa. Programs that combine
  75. * locking and mapping should be prepared for this combination to fail.
  76. *
  77. * <p> On some systems, closing a channel releases all locks held by the Java
  78. * virtual machine on the underlying file regardless of whether the locks were
  79. * acquired via that channel or via another channel open on the same file. It
  80. * is strongly recommended that, within a program, a unique channel be used to
  81. * acquire all locks on any given file.
  82. *
  83. * <p> Some network filesystems permit file locking to be used with
  84. * memory-mapped files only when the locked regions are page-aligned and a
  85. * whole multiple of the underlying hardware's page size. Some network
  86. * filesystems do not implement file locks on regions that extend past a
  87. * certain position, often 2<sup>30</sup> or 2<sup>31</sup>. In general, great
  88. * care should be taken when locking files that reside on network filesystems.
  89. *
  90. *
  91. * @author Mark Reinhold
  92. * @author JSR-51 Expert Group
  93. * @version 1.8, 03/12/19
  94. * @since 1.4
  95. */
  96. public abstract class FileLock {
  97. private final FileChannel channel;
  98. private final long position;
  99. private final long size;
  100. private final boolean shared;
  101. /**
  102. * Initializes a new instance of this class. </p>
  103. *
  104. * @param channel
  105. * The file channel upon whose file this lock is held
  106. *
  107. * @param position
  108. * The position within the file at which the locked region starts;
  109. * must be non-negative
  110. *
  111. * @param size
  112. * The size of the locked region; must be non-negative, and the sum
  113. * <tt>position</tt> + <tt>size</tt> must be non-negative
  114. *
  115. * @param shared
  116. * <tt>true</tt> if this lock is shared,
  117. * <tt>false</tt> if it is exclusive
  118. *
  119. * @throws IllegalArgumentException
  120. * If the preconditions on the parameters do not hold
  121. */
  122. protected FileLock(FileChannel channel,
  123. long position, long size, boolean shared)
  124. {
  125. if (position < 0)
  126. throw new IllegalArgumentException("Negative position");
  127. if (size < 0)
  128. throw new IllegalArgumentException("Negative size");
  129. if (position + size < 0)
  130. throw new IllegalArgumentException("Negative position + size");
  131. this.channel = channel;
  132. this.position = position;
  133. this.size = size;
  134. this.shared = shared;
  135. }
  136. /**
  137. * Returns the file channel upon whose file this lock is held. </p>
  138. *
  139. * @return The file channel
  140. */
  141. public final FileChannel channel() {
  142. return channel;
  143. }
  144. /**
  145. * Returns the position within the file of the first byte of the locked
  146. * region.
  147. *
  148. * <p> A locked region need not be contained within, or even overlap, the
  149. * actual underlying file, so the value returned by this method may exceed
  150. * the file's current size. </p>
  151. *
  152. * @return The position
  153. */
  154. public final long position() {
  155. return position;
  156. }
  157. /**
  158. * Returns the size of the locked region in bytes.
  159. *
  160. * <p> A locked region need not be contained within, or even overlap, the
  161. * actual underlying file, so the value returned by this method may exceed
  162. * the file's current size. </p>
  163. *
  164. * @return The size of the locked region
  165. */
  166. public final long size() {
  167. return size;
  168. }
  169. /**
  170. * Tells whether this lock is shared. </p>
  171. *
  172. * @return <tt>true</tt> if lock is shared,
  173. * <tt>false</tt> if it is exclusive
  174. */
  175. public final boolean isShared() {
  176. return shared;
  177. }
  178. /**
  179. * Tells whether or not this lock overlaps the given lock range. </p>
  180. *
  181. * @return <tt>true</tt> if, and only if, this lock and the given lock
  182. * range overlap by at least one byte
  183. */
  184. public final boolean overlaps(long position, long size) {
  185. if (position + size <= this.position)
  186. return false; // That is below this
  187. if (this.position + this.size <= position)
  188. return false; // This is below that
  189. return true;
  190. }
  191. /**
  192. * Tells whether or not this lock is valid.
  193. *
  194. * <p> A lock object remains valid until it is released or the associated
  195. * file channel is closed, whichever comes first. </p>
  196. *
  197. * @return <tt>true</tt> if, and only if, this lock is valid
  198. */
  199. public abstract boolean isValid();
  200. /**
  201. * Releases this lock.
  202. *
  203. * <p> If this lock object is valid then invoking this method releases the
  204. * lock and renders the object invalid. If this lock object is invalid
  205. * then invoking this method has no effect. </p>
  206. *
  207. * @throws ClosedChannelException
  208. * If the channel that was used to acquire this lock
  209. * is no longer open
  210. *
  211. * @throws IOException
  212. * If an I/O error occurs
  213. */
  214. public abstract void release() throws IOException;
  215. /**
  216. * Returns a string describing the range, type, and validity of this lock.
  217. *
  218. * @return A descriptive string
  219. */
  220. public final String toString() {
  221. return (this.getClass().getName()
  222. + "[" + position
  223. + ":" + size
  224. + " " + (shared ? "shared" : "exclusive")
  225. + " " + (isValid() ? "valid" : "invalid")
  226. + "]");
  227. }
  228. }