throw new FileLockInterruptionException(); } } return fli; } public FileLock tryLock(long position, long size, boolean shared) throws IOException { ensureOpen(); if (shared && !readable) throw new NonReadableChannelException(); if (!shared && !writable) throw new NonWritableChannelException(); FileLockImpl fli = new FileLockImpl(this, position, size, shared); FileLockTable flt = fileLockTable(); flt.add(fli); int result; int ti = threads.add(); try { try { ensureOpen(); result = nd.lock(fd, false, position, size, shared); } catch (IOException e) { flt.remove(fli); throw e; } if (result == FileDispatcher.NO_LOCK) { flt.remove(fli); return null; } if (result == FileDispatcher.RET_EX_LOCK) { assert shared; FileLockImpl fli2 = new FileLockImpl(this, position, size, false); flt.replace(fli, fli2); return fli2; } return fli; } finally { threads.remove(ti); } } void release(FileLockImpl fli) throws IOException { int ti = threads.add(); try { ensureOpen(); nd.release(fd, fli.position(), fli.size()); } finally { threads.remove(ti); } assert fileLockTable != null; fileLockTable.remove(fli); } // -- File lock support -- /** * A simple file lock table that maintains a list of FileLocks obtained by a * FileChannel. Use to get 1.4/5.0 behaviour. */ private static class SimpleFileLockTable extends FileLockTable { // synchronize on list for access private final List<FileLock> lockList = new ArrayList<FileLock>(2); public SimpleFileLockTable() { } private void checkList(long position, long size) throws OverlappingFileLockException { assert Thread.holdsLock(lockList); for (FileLock fl: lockList) { if (fl.overlaps(position, size)) { throw new OverlappingFileLockException(); } } } public void add(FileLock fl) throws OverlappingFileLockException { synchronized (lockList) { checkList(fl.position(), fl.size()); lockList.add(fl); } } public void remove(FileLock fl) { synchronized (lockList) { lockList.remove(fl); } } public List<FileLock> removeAll() { synchronized(lockList) { List<FileLock> result = new ArrayList<FileLock>(lockList); lockList.clear(); return result; } } public void replace(FileLock fl1, FileLock fl2) { synchronized (lockList) { lockList.remove(fl1); lockList.add(fl2); } } } // -- Native methods -- // Creates a new mapping private native long map0(int prot, long position, long length) throws IOException; // Removes an existing mapping private static native int unmap0(long address, long length); // Transfers from src to dst, or returns -2 if kernel can't do that private native long transferTo0(int src, long position, long count, int dst); // Sets or reports this file's position // If offset is -1, the current position is returned // otherwise the position is set to offset private native long position0(FileDescriptor fd, long offset); // Caches fieldIDs private static native long initIDs(); static { Util.load(); allocationGranularity = initIDs(); } }Lines 1001–1136 of 1136. Previous lines
throw new FileLockInterruptionException(); } } return fli; } public FileLock tryLock(long position, long size, boolean shared) throws IOException { ensureOpen(); if (shared && !readable) throw new NonReadableChannelException(); if (!shared && !writable) throw new NonWritableChannelException(); FileLockImpl fli = new FileLockImpl(this, position, size, shared); FileLockTable flt = fileLockTable(); flt.add(fli); int result; int ti = threads.add(); try { try { ensureOpen(); result = nd.lock(fd, false, position, size, shared); } catch (IOException e) { flt.remove(fli); throw e; } if (result == FileDispatcher.NO_LOCK) { flt.remove(fli); return null; } if (result == FileDispatcher.RET_EX_LOCK) { assert shared; FileLockImpl fli2 = new FileLockImpl(this, position, size, false); flt.replace(fli, fli2); return fli2; } return fli; } finally { threads.remove(ti); } } void release(FileLockImpl fli) throws IOException { int ti = threads.add(); try { ensureOpen(); nd.release(fd, fli.position(), fli.size()); } finally { threads.remove(ti); } assert fileLockTable != null; fileLockTable.remove(fli); } // -- File lock support -- /** * A simple file lock table that maintains a list of FileLocks obtained by a * FileChannel. Use to get 1.4/5.0 behaviour. */ private static class SimpleFileLockTable extends FileLockTable { // synchronize on list for access private final List<FileLock> lockList = new ArrayList<FileLock>(2); public SimpleFileLockTable() { } private void checkList(long position, long size) throws OverlappingFileLockException { assert Thread.holdsLock(lockList); for (FileLock fl: lockList) { if (fl.overlaps(position, size)) { throw new OverlappingFileLockException(); } } } public void add(FileLock fl) throws OverlappingFileLockException { synchronized (lockList) { checkList(fl.position(), fl.size()); lockList.add(fl); } } public void remove(FileLock fl) { synchronized (lockList) { lockList.remove(fl); } } public List<FileLock> removeAll() { synchronized(lockList) { List<FileLock> result = new ArrayList<FileLock>(lockList); lockList.clear(); return result; } } public void replace(FileLock fl1, FileLock fl2) { synchronized (lockList) { lockList.remove(fl1); lockList.add(fl2); } } } // -- Native methods -- // Creates a new mapping private native long map0(int prot, long position, long length) throws IOException; // Removes an existing mapping private static native int unmap0(long address, long length); // Transfers from src to dst, or returns -2 if kernel can't do that private native long transferTo0(int src, long position, long count, int dst); // Sets or reports this file's position // If offset is -1, the current position is returned // otherwise the position is set to offset private native long position0(FileDescriptor fd, long offset); // Caches fieldIDs private static native long initIDs(); static { Util.load(); allocationGranularity = initIDs(); } }