Home | History | Annotate | Download | only in internal
      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      */
     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      */
     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      */
     77     synchronized void removeLock(FileLock lock) {
     78         locks.remove(lock);
     79     }
     80 }
     81