blob: 3504460c125e355ab2109cb9dcaad3525705a974 [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.harmony.nio.internal;
import java.nio.channels.FileLock;
import java.nio.channels.OverlappingFileLockException;
import java.util.Comparator;
import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* The lock manager is responsible for tracking acquired and pending locks on
* the underlying file channel.
*
*/
final class LockManager {
// The set of acquired and pending locks.
private final Comparator<FileLock> lockComparator = new Comparator<FileLock>() {
public int compare(FileLock lock1, FileLock lock2) {
long position1 = lock1.position();
long position2 = lock2.position();
return position1 > position2 ? 1 : (position1 < position2 ? -1 : 0);
}
};
private final SortedSet<FileLock> locks = new TreeSet<FileLock>(
lockComparator);
/*
* Default Constructor.
*/
protected LockManager() {
super();
}
/*
* Add a new pending lock to the manager. Throws an exception if the lock
* would overlap an existing lock. Once the lock is acquired it remains in
* this set as an acquired lock.
*/
synchronized void addLock(FileLock lock)
throws OverlappingFileLockException {
long lockEnd = lock.position() + lock.size();
for (Iterator<FileLock> keyItr = locks.iterator(); keyItr.hasNext();) {
FileLock existingLock = keyItr.next();
if (existingLock.position() > lockEnd) {
// This, and all remaining locks, start beyond our end (so
// cannot overlap).
break;
}
if (existingLock.overlaps(lock.position(), lock.size())) {
throw new OverlappingFileLockException();
}
}
locks.add(lock);
}
/*
* Removes an acquired lock from the lock manager. If the lock did not exist
* in the lock manager the operation is a no-op.
*/
synchronized void removeLock(FileLock lock) {
locks.remove(lock);
}
}