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