1 /* Licensed to the Apache Software Foundation (ASF) under one or more 2 * contributor license agreements. See the NOTICE file distributed with 3 * this work for additional information regarding copyright ownership. 4 * The ASF licenses this file to You under the Apache License, Version 2.0 5 * (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.harmony.nio.internal; 18 19 import java.nio.channels.FileLock; 20 import java.nio.channels.OverlappingFileLockException; 21 import java.util.Comparator; 22 import java.util.Iterator; 23 import java.util.SortedSet; 24 import java.util.TreeSet; 25 26 /** 27 * The lock manager is responsible for tracking acquired and pending locks on 28 * the underlying file channel. 29 * 30 */ 31 final class LockManager { 32 // The set of acquired and pending locks. 33 private final Comparator<FileLock> lockComparator = new Comparator<FileLock>() { 34 public int compare(FileLock lock1, FileLock lock2) { 35 long position1 = lock1.position(); 36 long position2 = lock2.position(); 37 return position1 > position2 ? 1 : (position1 < position2 ? -1 : 0); 38 } 39 }; 40 41 private final SortedSet<FileLock> locks = new TreeSet<FileLock>( 42 lockComparator); 43 44 /* 45 * Default Constructor. 46 */ LockManager()47 protected LockManager() { 48 super(); 49 } 50 51 /* 52 * Add a new pending lock to the manager. Throws an exception if the lock 53 * would overlap an existing lock. Once the lock is acquired it remains in 54 * this set as an acquired lock. 55 */ addLock(FileLock lock)56 synchronized void addLock(FileLock lock) 57 throws OverlappingFileLockException { 58 long lockEnd = lock.position() + lock.size(); 59 for (Iterator<FileLock> keyItr = locks.iterator(); keyItr.hasNext();) { 60 FileLock existingLock = keyItr.next(); 61 if (existingLock.position() > lockEnd) { 62 // This, and all remaining locks, start beyond our end (so 63 // cannot overlap). 64 break; 65 } 66 if (existingLock.overlaps(lock.position(), lock.size())) { 67 throw new OverlappingFileLockException(); 68 } 69 } 70 locks.add(lock); 71 } 72 73 /* 74 * Removes an acquired lock from the lock manager. If the lock did not exist 75 * in the lock manager the operation is a no-op. 76 */ removeLock(FileLock lock)77 synchronized void removeLock(FileLock lock) { 78 locks.remove(lock); 79 } 80 } 81