59 * Remove an existing file lock from the table. |
59 * Remove an existing file lock from the table. |
60 */ |
60 */ |
61 public abstract void remove(FileLock fl); |
61 public abstract void remove(FileLock fl); |
62 |
62 |
63 /** |
63 /** |
64 * An implementation of this interface releases a given file lock. |
|
65 * Used with removeAll. |
|
66 */ |
|
67 public abstract interface Releaser { |
|
68 void release(FileLock fl) throws IOException; |
|
69 } |
|
70 |
|
71 /** |
|
72 * Removes all file locks from the table. |
64 * Removes all file locks from the table. |
73 * <p> |
|
74 * The Releaser#release method is invoked for each file lock before |
|
75 * it is removed. |
|
76 * |
65 * |
77 * @throws IOException if the release method throws IOException |
66 * @return The list of file locks removed |
78 */ |
67 */ |
79 public abstract void removeAll(Releaser r) throws IOException; |
68 public abstract List<FileLock> removeAll(); |
80 |
69 |
81 /** |
70 /** |
82 * Replaces an existing file lock in the table. |
71 * Replaces an existing file lock in the table. |
83 */ |
72 */ |
84 public abstract void replace(FileLock fl1, FileLock fl2); |
73 public abstract void replace(FileLock fl1, FileLock fl2); |
193 int index = 0; |
182 int index = 0; |
194 while (index < list.size()) { |
183 while (index < list.size()) { |
195 FileLockReference ref = list.get(index); |
184 FileLockReference ref = list.get(index); |
196 FileLock lock = ref.get(); |
185 FileLock lock = ref.get(); |
197 if (lock == fl) { |
186 if (lock == fl) { |
198 assert (lock != null) && (lock.channel() == channel); |
187 assert (lock != null) && (lock.acquiredBy() == channel); |
199 ref.clear(); |
188 ref.clear(); |
200 list.remove(index); |
189 list.remove(index); |
201 break; |
190 break; |
202 } |
191 } |
203 index++; |
192 index++; |
204 } |
193 } |
205 } |
194 } |
206 } |
195 } |
207 |
196 |
208 @Override |
197 @Override |
209 public void removeAll(Releaser releaser) throws IOException { |
198 public List<FileLock> removeAll() { |
|
199 List<FileLock> result = new ArrayList<FileLock>(); |
210 List<FileLockReference> list = lockMap.get(fileKey); |
200 List<FileLockReference> list = lockMap.get(fileKey); |
211 if (list != null) { |
201 if (list != null) { |
212 synchronized (list) { |
202 synchronized (list) { |
213 int index = 0; |
203 int index = 0; |
214 while (index < list.size()) { |
204 while (index < list.size()) { |
215 FileLockReference ref = list.get(index); |
205 FileLockReference ref = list.get(index); |
216 FileLock lock = ref.get(); |
206 FileLock lock = ref.get(); |
217 |
207 |
218 // remove locks obtained by this channel |
208 // remove locks obtained by this channel |
219 if (lock != null && lock.channel() == channel) { |
209 if (lock != null && lock.acquiredBy() == channel) { |
220 // invoke the releaser to invalidate/release the lock |
|
221 releaser.release(lock); |
|
222 |
|
223 // remove the lock from the list |
210 // remove the lock from the list |
224 ref.clear(); |
211 ref.clear(); |
225 list.remove(index); |
212 list.remove(index); |
|
213 |
|
214 // add to result |
|
215 result.add(lock); |
226 } else { |
216 } else { |
227 index++; |
217 index++; |
228 } |
218 } |
229 } |
219 } |
230 |
220 |
231 // once the lock list is empty we remove it from the map |
221 // once the lock list is empty we remove it from the map |
232 removeKeyIfEmpty(fileKey, list); |
222 removeKeyIfEmpty(fileKey, list); |
233 } |
223 } |
234 } |
224 } |
|
225 return result; |
235 } |
226 } |
236 |
227 |
237 @Override |
228 @Override |
238 public void replace(FileLock fromLock, FileLock toLock) { |
229 public void replace(FileLock fromLock, FileLock toLock) { |
239 // the lock must exist so there must be a list |
230 // the lock must exist so there must be a list |