< prev index next >

src/java.base/share/classes/sun/nio/ch/FileLockTable.java

Print this page

        

*** 1,7 **** /* ! * Copyright (c) 2005, 2009, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this --- 1,7 ---- /* ! * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 84,105 **** * <p> * SharedFileLockTable uses a list of file lock references to avoid keeping the * FileLock (and FileChannel) alive. */ private static class FileLockReference extends WeakReference<FileLock> { ! private FileKey fileKey; FileLockReference(FileLock referent, ReferenceQueue<FileLock> queue, FileKey key) { super(referent, queue); this.fileKey = key; } FileKey fileKey() { return fileKey; } } // The system-wide map is a ConcurrentHashMap that is keyed on the FileKey. // The map value is a list of file locks represented by FileLockReferences. // All access to the list must be synchronized on the list. --- 84,126 ---- * <p> * SharedFileLockTable uses a list of file lock references to avoid keeping the * FileLock (and FileChannel) alive. */ private static class FileLockReference extends WeakReference<FileLock> { ! private final FileKey fileKey; ! final long position; ! final long size; ! private volatile boolean invalid; FileLockReference(FileLock referent, ReferenceQueue<FileLock> queue, FileKey key) { super(referent, queue); this.fileKey = key; + this.position = referent.position(); + this.size = referent.size(); } FileKey fileKey() { return fileKey; } + + void invalidate() { + invalid = true; + } + + boolean isValid() { + return !invalid; + } + + boolean overlaps(long position, long size) { + if (position + size <= this.position) + return false; // That is below this + if (this.position + this.size <= position) + return false; // This is below that + return true; + } } // The system-wide map is a ConcurrentHashMap that is keyed on the FileKey. // The map value is a list of file locks represented by FileLockReferences. // All access to the list must be synchronized on the list.
*** 184,193 **** --- 205,215 ---- FileLockReference ref = list.get(index); FileLock lock = ref.get(); if (lock == fl) { assert (lock != null) && (lock.acquiredBy() == channel); ref.clear(); + ref.invalidate(); list.remove(index); break; } index++; }
*** 207,216 **** --- 229,239 ---- // remove locks obtained by this channel if (lock != null && lock.acquiredBy() == channel) { // remove the lock from the list ref.clear(); + ref.invalidate(); list.remove(index); // add to result result.add(lock); } else {
*** 249,259 **** throws OverlappingFileLockException { assert Thread.holdsLock(list); for (FileLockReference ref: list) { FileLock fl = ref.get(); ! if (fl != null && fl.overlaps(position, size)) throw new OverlappingFileLockException(); } } // Process the reference queue --- 272,282 ---- throws OverlappingFileLockException { assert Thread.holdsLock(list); for (FileLockReference ref: list) { FileLock fl = ref.get(); ! if ((fl != null || ref.isValid()) && ref.overlaps(position, size)) throw new OverlappingFileLockException(); } } // Process the reference queue
*** 262,272 **** --- 285,297 ---- while ((ref = (FileLockReference)queue.poll()) != null) { FileKey fk = ref.fileKey(); List<FileLockReference> list = lockMap.get(fk); if (list != null) { synchronized (list) { + if (!ref.isValid()) { list.remove(ref); + } removeKeyIfEmpty(fk, list); } } } }
< prev index next >