151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 3519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage sun.nio.ch; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 295ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport android.system.ErrnoException; 305ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 3151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.FileDescriptor; 3251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.io.IOException; 3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.ByteBuffer; 34fe0e5d3e460de87d24e0224ef10b089289355c47Narayan Kamathimport java.nio.DirectByteBuffer; 3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.MappedByteBuffer; 365ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ClosedByInterruptException; 375ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ClosedChannelException; 385ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.FileChannel; 395ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.FileLock; 405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.FileLockInterruptionException; 415ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NonReadableChannelException; 425ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.NonWritableChannelException; 435ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.OverlappingFileLockException; 445ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.ReadableByteChannel; 455ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.SelectableChannel; 465ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.nio.channels.WritableByteChannel; 475ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport java.security.AccessController; 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.ArrayList; 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.util.List; 505ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport libcore.io.Libcore; 515873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath 52e31b37859051d3902e06e4ba384995df7188917fHans Boehmimport dalvik.annotation.optimization.ReachabilitySensitive; 535873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport dalvik.system.BlockGuard; 545ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmeraimport dalvik.system.CloseGuard; 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.misc.Cleaner; 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.security.action.GetPropertyAction; 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class FileChannelImpl 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski extends FileChannel 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Memory allocation size for mapping buffers 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long allocationGranularity; 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used to make native read and write calls 6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final FileDispatcher nd; 6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // File descriptor 68e31b37859051d3902e06e4ba384995df7188917fHans Boehm // Android-added: @ReachabilitySensitive 69e31b37859051d3902e06e4ba384995df7188917fHans Boehm // If this were reclaimed while we're in an operation on fd, the associated Stream 70e31b37859051d3902e06e4ba384995df7188917fHans Boehm // could be finalized, closing the fd while still in use. This is not the case upstream, 71e31b37859051d3902e06e4ba384995df7188917fHans Boehm // since there the Stream is accessible from the FileDescriptor. 72e31b37859051d3902e06e4ba384995df7188917fHans Boehm // Android-changed: make public. Used by NioUtils.getFD(), and possibly others. 73e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 743d43823e17818b3c5f45831f830884917b181454Piotr Jastrzebski public final FileDescriptor fd; 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // File access mode (immutable) 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean writable; 7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean readable; 7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean append; 8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Required to prevent finalization of creating stream (immutable) 8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object parent; 8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // The path of the referenced file 85519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // (null if the parent stream is created with a file descriptor) 8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final String path; 8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Thread-safe set of IDs of native threads, for signalling 8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final NativeThreadSet threads = new NativeThreadSet(2); 9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Lock for operations involving position and size 9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final Object positionLock = new Object(); 9351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 94dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 95e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 965ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera private final CloseGuard guard = CloseGuard.get(); 975ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private FileChannelImpl(FileDescriptor fd, String path, boolean readable, 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean writable, boolean append, Object parent) 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.readable = readable; 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.writable = writable; 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.append = append; 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.parent = parent; 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.path = path; 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.nd = new FileDispatcherImpl(append); 108dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 1095ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (fd != null && fd.valid()) { 1105ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.open("close"); 1115ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel() 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static FileChannel open(FileDescriptor fd, String path, 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean readable, boolean writable, 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Object parent) 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new FileChannelImpl(fd, path, readable, writable, false, parent); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Used by FileOutputStream.getChannel 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public static FileChannel open(FileDescriptor fd, String path, 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean readable, boolean writable, 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean append, Object parent) 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return new FileChannelImpl(fd, path, readable, writable, append, parent); 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void ensureOpen() throws IOException { 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Standard channel operations -- 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void implCloseChannel() throws IOException { 139dd2c67a47dc742e19c6710ddd6e1b85f95dd1d1fNeil Fuller // Android-added: CloseGuard support. 1405ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.close(); 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Release and invalidate any locks that we still hold 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fileLockTable != null) { 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (FileLock fl: fileLockTable.removeAll()) { 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (fl) { 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fl.isValid()) { 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.release(fd, fl.position(), fl.size()); 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((FileLockImpl)fl).invalidate(); 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 153519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // signal any threads blocked on this channel 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.signalAndWait(); 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (parent != null) { 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Close the fd via the parent stream's close method. The parent 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // will reinvoke our close method, which is defined in the 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // superclass AbstractInterruptibleChannel, but the isOpen logic in 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // that method will prevent this method from being reinvoked. 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ((java.io.Closeable)parent).close(); 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 1705ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera protected void finalize() throws Throwable { 1715ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera try { 1725ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera if (guard != null) { 1735ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera guard.warnIfOpen(); 1745ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 1755ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera close(); 1765ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } finally { 1775ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera super.finalize(); 1785ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 1795ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera } 1805ba24bd205f9c8ed2179a0a32859a529a795a4c3Shubham Ajmera 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(ByteBuffer dst) throws IOException { 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!readable) 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, dst, -1, nd); 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long read(ByteBuffer[] dsts, int offset, int length) 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > dsts.length - length)) 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!readable) 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, dsts, offset, length, nd); 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int write(ByteBuffer src) throws IOException { 23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) 23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, src, -1, nd); 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long write(ByteBuffer[] srcs, int offset, int length) 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((offset < 0) || (length < 0) || (offset > srcs.length - length)) 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IndexOutOfBoundsException(); 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = 0; 26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 27151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, srcs, offset, length, nd); 27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Other operations -- 28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long position() throws IOException { 28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long p = -1; 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 2975873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath if (append) { 2985873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath BlockGuard.getThreadPolicy().onWriteToDisk(); 2995873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath } 30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // in append-mode then position is advanced to end before writing 30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p = (append) ? nd.size(fd) : position0(fd, -1); 30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((p == IOStatus.INTERRUPTED) && isOpen()); 30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(p); 30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(p > -1); 30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(p); 30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileChannel position(long newPosition) throws IOException { 31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (newPosition < 0) 31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException(); 31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long p = -1; 31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 32151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 32251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 3255873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath BlockGuard.getThreadPolicy().onReadFromDisk(); 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p = position0(fd, newPosition); 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((p == IOStatus.INTERRUPTED) && isOpen()); 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 33151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 33251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(p > -1); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(p); 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 33851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long size() throws IOException { 33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long s = -1; 34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski s = nd.size(fd); 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((s == IOStatus.INTERRUPTED) && isOpen()); 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(s); 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(s > -1); 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(s); 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 35951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 360519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera public FileChannel truncate(long newSize) throws IOException { 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 362519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (newSize < 0) 363519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera throw new IllegalArgumentException("Negative size"); 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rv = -1; 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long p = -1; 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 37251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 37351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 37451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 37551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 376519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // get current size 377519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera long size; 378519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera do { 379519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera size = nd.size(fd); 380519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } while ((size == IOStatus.INTERRUPTED) && isOpen()); 381519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!isOpen()) 382519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return null; 383519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // get current position 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p = position0(fd, -1); 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((p == IOStatus.INTERRUPTED) && isOpen()); 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert p >= 0; 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 392519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // truncate file if given size is less than the current size 393519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (newSize < size) { 3944acee6319a676b9990a0768f57457fb54b007970Przemyslaw Szczepaniak do { 395519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera rv = nd.truncate(fd, newSize); 3964acee6319a676b9990a0768f57457fb54b007970Przemyslaw Szczepaniak } while ((rv == IOStatus.INTERRUPTED) && isOpen()); 3974acee6319a676b9990a0768f57457fb54b007970Przemyslaw Szczepaniak if (!isOpen()) 3984acee6319a676b9990a0768f57457fb54b007970Przemyslaw Szczepaniak return null; 3994acee6319a676b9990a0768f57457fb54b007970Przemyslaw Szczepaniak } 400519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 401519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // if position is beyond new size then adjust it 402519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (p > newSize) 403519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera p = newSize; 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 40551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rv = (int)position0(fd, p); 40651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((rv == IOStatus.INTERRUPTED) && isOpen()); 40751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return this; 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(rv > -1); 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(rv); 41251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void force(boolean metaData) throws IOException { 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int rv = -1; 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski rv = nd.force(fd, metaData); 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((rv == IOStatus.INTERRUPTED) && isOpen()); 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 42951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 43051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(rv > -1); 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(rv); 43251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume at first that the underlying kernel supports sendfile(); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // set this to false if we find out later that it doesn't 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static volatile boolean transferSupported = true; 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume that the underlying kernel sendfile() will work if the target 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd is a pipe; set this to false if we find out later that it doesn't 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 44351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static volatile boolean pipeSupported = true; 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Assume that the underlying kernel sendfile() will work if the target 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // fd is a file; set this to false if we find out later that it doesn't 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static volatile boolean fileSupported = true; 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 450519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera private long transferToDirectlyInternal(long position, int icount, 451519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera WritableByteChannel target, 452519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera FileDescriptor targetFD) 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 455519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera assert !nd.transferToDirectlyNeedsPositionLock() || 456519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera Thread.holdsLock(positionLock); 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = -1; 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 4655873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath BlockGuard.getThreadPolicy().onWriteToDisk(); 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 467519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera n = transferTo0(fd, position, icount, targetFD); 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == IOStatus.UNSUPPORTED_CASE) { 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (target instanceof SinkChannelImpl) 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pipeSupported = false; 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (target instanceof FileChannelImpl) 47351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileSupported = false; 47451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.UNSUPPORTED_CASE; 47551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 47651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == IOStatus.UNSUPPORTED) { 47751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Don't bother trying again 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski transferSupported = false; 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.UNSUPPORTED; 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 48251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 48351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end (n > -1); 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 488519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera private long transferToDirectly(long position, int icount, 489519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera WritableByteChannel target) 490519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera throws IOException 491519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera { 492519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!transferSupported) 493519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED; 494519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 495519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera FileDescriptor targetFD = null; 496519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (target instanceof FileChannelImpl) { 497519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!fileSupported) 498519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED_CASE; 499519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera targetFD = ((FileChannelImpl)target).fd; 500519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } else if (target instanceof SelChImpl) { 501519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // Direct transfer to pipe causes EINVAL on some configurations 502519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if ((target instanceof SinkChannelImpl) && !pipeSupported) 503519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED_CASE; 504519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 505519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // Platform-specific restrictions. Now there is only one: 506519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera // Direct transfer to non-blocking channel could be forbidden 507519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera SelectableChannel sc = (SelectableChannel)target; 508519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!nd.canTransferToDirectly(sc)) 509519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED_CASE; 510519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 511519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera targetFD = ((SelChImpl)target).getFD(); 512519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 513519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 514519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (targetFD == null) 515519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED; 516519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int thisFDVal = IOUtil.fdVal(fd); 517519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera int targetFDVal = IOUtil.fdVal(targetFD); 518519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (thisFDVal == targetFDVal) // Not supported on some configurations 519519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return IOStatus.UNSUPPORTED; 520519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 521519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (nd.transferToDirectlyNeedsPositionLock()) { 522519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera synchronized (positionLock) { 523519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera long pos = position(); 524519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera try { 525519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return transferToDirectlyInternal(position, icount, 526519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera target, targetFD); 527519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } finally { 528519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera position(pos); 529519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 530519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 531519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } else { 532519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return transferToDirectlyInternal(position, icount, target, targetFD); 533519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 534519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } 535519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 53651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Maximum size to map when using a mapped buffer 53751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final long MAPPED_TRANSFER_SIZE = 8L*1024L*1024L; 53851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 53951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long transferToTrustedChannel(long position, long count, 54051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski WritableByteChannel target) 54151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 54251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 54351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean isSelChImpl = (target instanceof SelChImpl); 54451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!((target instanceof FileChannelImpl) || isSelChImpl)) 54551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.UNSUPPORTED; 54651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 54751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Trusted target: Use a mapped buffer 54851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long remaining = count; 54951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (remaining > 0L) { 55051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long size = Math.min(remaining, MAPPED_TRANSFER_SIZE); 55151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 55251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MappedByteBuffer dbb = map(MapMode.READ_ONLY, position, size); 55351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 55451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Bug: Closing this channel will not terminate the write 55551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = target.write(dbb); 55651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert n >= 0; 55751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remaining -= n; 55851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isSelChImpl) { 55951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // one attempt to write to selectable channel 56051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 56151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert n > 0; 56351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski position += n; 56451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 56551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unmap(dbb); 56651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 56751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClosedByInterruptException e) { 56851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // target closed by interrupt as ClosedByInterruptException needs 56951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // to be thrown after closing this channel. 57051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !target.isOpen(); 57151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 57251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski close(); 57351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (Throwable suppressed) { 57451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski e.addSuppressed(suppressed); 57551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 57651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw e; 57751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 57851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Only throw exception if no bytes have been written 57951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (remaining == count) 58051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ioe; 58151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 58251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return count - remaining; 58551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 58651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 58751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long transferToArbitraryChannel(long position, int icount, 58851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski WritableByteChannel target) 58951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 59051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 59151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Untrusted target: Use a newly-erased buffer 59251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c = Math.min(icount, TRANSFER_SIZE); 59351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteBuffer bb = Util.getTemporaryDirectBuffer(c); 59451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long tw = 0; // Total bytes written 59551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long pos = position; 59651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 59751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.erase(bb); 59851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (tw < icount) { 59951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.limit(Math.min((int)(icount - tw), TRANSFER_SIZE)); 60051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nr = read(bb, pos); 60151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nr <= 0) 60251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 60351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 60451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Bug: Will block writing target if this channel 60551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## is asynchronously closed 60651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nw = target.write(bb); 60751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tw += nw; 60851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nw != nr) 60951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 61051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += nw; 61151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.clear(); 61251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 61351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return tw; 61451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException x) { 61551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tw > 0) 61651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return tw; 61751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 61851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 61951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.releaseTemporaryDirectBuffer(bb); 62051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 62251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 62351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long transferTo(long position, long count, 62451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski WritableByteChannel target) 62551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 62651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 62751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 62851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!target.isOpen()) 62951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 63051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!readable) 63151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 63251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (target instanceof FileChannelImpl && 63351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski !((FileChannelImpl)target).writable) 63451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 63551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((position < 0) || (count < 0)) 63651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException(); 63751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long sz = size(); 63851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position > sz) 63951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 64051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int icount = (int)Math.min(count, Integer.MAX_VALUE); 64151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((sz - position) < icount) 64251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski icount = (int)(sz - position); 64351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n; 64551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 64651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Attempt a direct transfer, if the kernel supports it 64751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n = transferToDirectly(position, icount, target)) >= 0) 64851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 64951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Attempt a mapped transfer, but only to trusted channel types 65151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((n = transferToTrustedChannel(position, icount, target)) >= 0) 65251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return n; 65351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Slow path for untrusted targets 65551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return transferToArbitraryChannel(position, icount, target); 65651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 65751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 65851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long transferFromFileChannel(FileChannelImpl src, 65951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long position, long count) 66051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 66151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 66251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!src.readable) 66351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 66451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (src.positionLock) { 66551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long pos = src.position(); 66651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long max = Math.min(count, src.size() - pos); 66751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 66851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long remaining = max; 66951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long p = pos; 67051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (remaining > 0L) { 67151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long size = Math.min(remaining, MAPPED_TRANSFER_SIZE); 67251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Bug: Closing this channel will not terminate the write 67351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski MappedByteBuffer bb = src.map(MapMode.READ_ONLY, p, size); 67451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 67551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long n = write(bb, position); 67651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert n > 0; 67751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski p += n; 67851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski position += n; 67951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski remaining -= n; 68051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 68151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Only throw exception if no bytes have been written 68251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (remaining == max) 68351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ioe; 68451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 68551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 68651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unmap(bb); 68751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 68951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long nwritten = max - remaining; 69051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski src.position(pos + nwritten); 69151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return nwritten; 69251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 69451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int TRANSFER_SIZE = 8192; 69651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 69751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private long transferFromArbitraryChannel(ReadableByteChannel src, 69851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long position, long count) 69951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 70051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 70151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Untrusted target: Use a newly-erased buffer 70251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int c = (int)Math.min(count, TRANSFER_SIZE); 70351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ByteBuffer bb = Util.getTemporaryDirectBuffer(c); 70451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long tw = 0; // Total bytes written 70551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long pos = position; 70651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 70751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.erase(bb); 70851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski while (tw < count) { 70951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.limit((int)Math.min((count - tw), (long)TRANSFER_SIZE)); 71051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## Bug: Will block reading src if this channel 71151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // ## is asynchronously closed 71251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nr = src.read(bb); 71351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nr <= 0) 71451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 71551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.flip(); 71651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int nw = write(bb, pos); 71751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski tw += nw; 71851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nw != nr) 71951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski break; 72051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski pos += nw; 72151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski bb.clear(); 72251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 72351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return tw; 72451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException x) { 72551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (tw > 0) 72651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return tw; 72751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw x; 72851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 72951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Util.releaseTemporaryDirectBuffer(bb); 73051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 73251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 73351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public long transferFrom(ReadableByteChannel src, 73451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long position, long count) 73551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 73651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 73751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 73851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!src.isOpen()) 73951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new ClosedChannelException(); 74051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) 74151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 74251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((position < 0) || (count < 0)) 74351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException(); 74451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position > size()) 74551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return 0; 74651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (src instanceof FileChannelImpl) 74751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return transferFromFileChannel((FileChannelImpl)src, 74851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski position, count); 74951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return transferFromArbitraryChannel(src, position, count); 75151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 75251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 75351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int read(ByteBuffer dst, long position) throws IOException { 75451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (dst == null) 75551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 75651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position < 0) 75751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Negative position"); 75851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!readable) 75951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 76051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 76151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nd.needsPositionLock()) { 76251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 76351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readInternal(dst, position); 76451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 76651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return readInternal(dst, position); 76751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 76951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 77051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int readInternal(ByteBuffer dst, long position) throws IOException { 77151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !nd.needsPositionLock() || Thread.holdsLock(positionLock); 77251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 77351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 77451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 77551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 77651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 77751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 77851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 77951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 78051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.read(fd, dst, position, nd); 78151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 78251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 78351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 78451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 78551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 78651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 78751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 78951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 79051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public int write(ByteBuffer src, long position) throws IOException { 79151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (src == null) 79251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 79351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position < 0) 79451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Negative position"); 79551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) 79651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 79751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 79851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (nd.needsPositionLock()) { 79951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (positionLock) { 80051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return writeInternal(src, position); 80151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 80351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return writeInternal(src, position); 80451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 80651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 80751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private int writeInternal(ByteBuffer src, long position) throws IOException { 80851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert !nd.needsPositionLock() || Thread.holdsLock(positionLock); 80951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n = 0; 81051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 81151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 81251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 81351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 81451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 81551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return -1; 81651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 81751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = IOUtil.write(fd, src, position, nd); 81851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == IOStatus.INTERRUPTED) && isOpen()); 81951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return IOStatus.normalize(n); 82051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 82151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 82251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(n > 0); 82351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert IOStatus.check(n); 82451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 82651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 82851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Memory-mapped buffers -- 82951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class Unmapper 83151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski implements Runnable 83251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 83351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // may be required to close file 83451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final NativeDispatcher nd = new FileDispatcherImpl(); 83551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 83651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // keep track of mapped buffer usage 83751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static volatile int count; 83851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static volatile long totalSize; 83951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static volatile long totalCapacity; 84051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile long address; 84251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final long size; 84351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final int cap; 84451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final FileDescriptor fd; 84551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 84651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private Unmapper(long address, long size, int cap, 84751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor fd) 84851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 84951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (address != 0); 85051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.address = address; 85151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.size = size; 85251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.cap = cap; 85351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fd; 85451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 85551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (Unmapper.class) { 85651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count++; 85751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski totalSize += size; 85851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski totalCapacity += cap; 85951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 86151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void run() { 86351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (address == 0) 86451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 86551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unmap0(address, size); 86651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski address = 0; 86751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 86851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // if this mapping has a valid file descriptor then we close it 86951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fd.valid()) { 87051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 87151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.close(fd); 87251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ignore) { 87351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // nothing we can do 87451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 87651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 87751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (Unmapper.class) { 87851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski count--; 87951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski totalSize -= size; 88051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski totalCapacity -= cap; 88151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 88451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 88551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static void unmap(MappedByteBuffer bb) { 88651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Cleaner cl = ((DirectBuffer)bb).cleaner(); 88751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (cl != null) 88851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski cl.clean(); 88951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 89051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MAP_RO = 0; 89251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MAP_RW = 1; 89351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static final int MAP_PV = 2; 89451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 89551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public MappedByteBuffer map(MapMode mode, long position, long size) 89651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 89751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 89851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 899519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (mode == null) 900519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera throw new NullPointerException("Mode is null"); 90151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position < 0L) 90251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Negative position"); 90351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size < 0L) 90451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Negative size"); 90551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (position + size < 0) 90651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Position + size overflow"); 90751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size > Integer.MAX_VALUE) 90851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE"); 909519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 91051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int imode = -1; 91151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (mode == MapMode.READ_ONLY) 91251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski imode = MAP_RO; 91351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (mode == MapMode.READ_WRITE) 91451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski imode = MAP_RW; 91551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski else if (mode == MapMode.PRIVATE) 91651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski imode = MAP_PV; 91751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (imode >= 0); 91851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if ((mode != MapMode.READ_ONLY) && !writable) 91951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 92051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!readable) 92151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 92251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 92351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long addr = -1; 92451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 92551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 92651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 92751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 92851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 92951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 930519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 931519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera long filesize; 932519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera do { 933519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera filesize = nd.size(fd); 934519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera } while ((filesize == IOStatus.INTERRUPTED) && isOpen()); 935519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!isOpen()) 936519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return null; 937519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera 938519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (filesize < position + size) { // Extend file size 9394087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer // BEGIN Android-changed 9404087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer /* 94151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!writable) { 94251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Channel not open for writing " + 94351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "- cannot extend file to required size"); 94451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 9454087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer */ 9464087011821a84f2a4e2b827f304bb00481d3d139Tobias Thierer // END Android-changed 9470f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak int rv = 0; 94851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 9496975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // BEGIN Android-changed 9500f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak //int rv = nd.truncate(fd, position + size); 9510f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak try { 9520f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak rv = nd.truncate(fd, position + size); 9530f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak } catch (IOException r) { 9540f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak try { 9550f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak // If we're dealing with non-regular files, for example, 9560f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak // character devices such as /dev/zero. In those 9570f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak // cases, we ignore the failed truncation and continue 9580f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak // on. 9590f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak if (android.system.OsConstants.S_ISREG(Libcore.os.fstat(fd).st_mode)) { 9600f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak throw r; 9610f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak } 9620f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak } catch (ErrnoException e) { 9630f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak e.rethrowAsIOException(); 9640f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak } 9650f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak break; 9660f7f0c999e751ab883a247e1409dcc8730c87b9fPrzemyslaw Szczepaniak } 9676975f84c2ed72e1e26d20190b6f318718c849008Tobias Thierer // END Android-changed 96851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((rv == IOStatus.INTERRUPTED) && isOpen()); 969519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera if (!isOpen()) 970519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera return null; 97151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 97251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (size == 0) { 97351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr = 0; 97451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // a valid file descriptor is not required 97551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor dummy = new FileDescriptor(); 976fe0e5d3e460de87d24e0224ef10b089289355c47Narayan Kamath return new DirectByteBuffer(0, 0, dummy, null, 977fe0e5d3e460de87d24e0224ef10b089289355c47Narayan Kamath (!writable) || (imode == MAP_RO) /* readOnly */); 97851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 97951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 98051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int pagePosition = (int)(position % allocationGranularity); 98151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long mapPosition = position - pagePosition; 98251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski long mapSize = size + pagePosition; 98351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 98451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If no exception was thrown from map0, the address is valid 9855873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath BlockGuard.getThreadPolicy().onReadFromDisk(); 98651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr = map0(imode, mapPosition, mapSize); 98751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (OutOfMemoryError x) { 98851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // An OutOfMemoryError may indicate that we've exhausted memory 98951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // so force gc and re-attempt map 99051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski System.gc(); 99151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 99251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Thread.sleep(100); 99351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (InterruptedException y) { 99451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Thread.currentThread().interrupt(); 99551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 99651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 99751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski addr = map0(imode, mapPosition, mapSize); 99851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (OutOfMemoryError y) { 99951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // After a second OOME, fail 100051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException("Map failed", y); 100151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 100351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 100451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // On Windows, and potentially other platforms, we need an open 100551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // file descriptor for some mapping operations. 100651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileDescriptor mfd; 100751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 100851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski mfd = nd.duplicateForMapping(fd); 100951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException ioe) { 101051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski unmap0(addr, mapSize); 101151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw ioe; 101251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 101351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 101451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (IOStatus.checkAll(addr)); 101551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert (addr % allocationGranularity == 0); 101651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int isize = (int)size; 101751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski Unmapper um = new Unmapper(addr, mapSize, isize, mfd); 1018fe0e5d3e460de87d24e0224ef10b089289355c47Narayan Kamath return new DirectByteBuffer(isize, addr + pagePosition, mfd, um, 1019fe0e5d3e460de87d24e0224ef10b089289355c47Narayan Kamath (!writable) || (imode == MAP_RO)); 102051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 102151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 102251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(IOStatus.checkAll(addr)); 102351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 102451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 102551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 102651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Locks -- 102751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 102851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // keeps track of locks on this file 102951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private volatile FileLockTable fileLockTable; 103051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // indicates if file locks are maintained system-wide (as per spec) 103251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static boolean isSharedFileLockTable; 103351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // indicates if the disableSystemWideOverlappingFileLockCheck property 103551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // has been checked 103651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static volatile boolean propertyChecked; 103751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 103851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // The lock list in J2SE 1.4/5.0 was local to each FileChannel instance so 103951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the overlap check wasn't system wide when there were multiple channels to 104051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // the same file. This property is used to get 1.4/5.0 behavior if desired. 104151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static boolean isSharedFileLockTable() { 104251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!propertyChecked) { 104351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (FileChannelImpl.class) { 104451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!propertyChecked) { 104551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String value = AccessController.doPrivileged( 104651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski new GetPropertyAction( 104751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski "sun.nio.ch.disableSystemWideOverlappingFileLockCheck")); 104851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski isSharedFileLockTable = ((value == null) || value.equals("false")); 104951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski propertyChecked = true; 105051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return isSharedFileLockTable; 105451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 105551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 105651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private FileLockTable fileLockTable() throws IOException { 105751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fileLockTable == null) { 105851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 105951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fileLockTable == null) { 106051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isSharedFileLockTable()) { 106151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = threads.add(); 106251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 106351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 106451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileLockTable = FileLockTable.newSharedFileLockTable(this, fd); 106551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 106651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 106751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 106851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 106951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileLockTable = new SimpleFileLockTable(); 107051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fileLockTable; 107551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 107651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 107751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileLock lock(long position, long size, boolean shared) 107851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 107951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 108051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 108151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (shared && !readable) 108251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 108351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!shared && !writable) 108451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 108551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockImpl fli = new FileLockImpl(this, position, size, shared); 108651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockTable flt = fileLockTable(); 108751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.add(fli); 108851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski boolean completed = false; 108951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = -1; 109051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 109151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski begin(); 109251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ti = threads.add(); 109351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!isOpen()) 109451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 109551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int n; 109651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski do { 109751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski n = nd.lock(fd, true, position, size, shared); 109851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } while ((n == FileDispatcher.INTERRUPTED) && isOpen()); 109951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (isOpen()) { 110051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (n == FileDispatcher.RET_EX_LOCK) { 110151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert shared; 110251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockImpl fli2 = new FileLockImpl(this, position, size, 110351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski false); 110451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.replace(fli, fli2); 110551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fli = fli2; 110651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 110751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski completed = true; 110851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 110951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 111051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!completed) 111151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.remove(fli); 111251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 111351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 111451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski end(completed); 111551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (ClosedByInterruptException e) { 111651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new FileLockInterruptionException(); 111751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 111951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fli; 112051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 112151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 112251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileLock tryLock(long position, long size, boolean shared) 112351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException 112451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 112551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 112651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (shared && !readable) 112751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonReadableChannelException(); 112851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (!shared && !writable) 112951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NonWritableChannelException(); 113051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockImpl fli = new FileLockImpl(this, position, size, shared); 113151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockTable flt = fileLockTable(); 113251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.add(fli); 113351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int result; 113451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 113551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = threads.add(); 113651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 113751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 113851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 113951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski result = nd.lock(fd, false, position, size, shared); 114051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } catch (IOException e) { 114151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.remove(fli); 114251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw e; 114351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (result == FileDispatcher.NO_LOCK) { 114551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.remove(fli); 114651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return null; 114751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 114851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (result == FileDispatcher.RET_EX_LOCK) { 114951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert shared; 115051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski FileLockImpl fli2 = new FileLockImpl(this, position, size, 115151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski false); 115251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flt.replace(fli, fli2); 115351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fli2; 115451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return fli; 115651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 115751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 115851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 115951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 116051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 116151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski void release(FileLockImpl fli) throws IOException { 116251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski int ti = threads.add(); 116351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski try { 116451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski ensureOpen(); 116551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski nd.release(fd, fli.position(), fli.size()); 116651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } finally { 116751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski threads.remove(ti); 116851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 116951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert fileLockTable != null; 117051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski fileLockTable.remove(fli); 117151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 117251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- File lock support -- 117451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 117551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 117651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A simple file lock table that maintains a list of FileLocks obtained by a 117751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FileChannel. Use to get 1.4/5.0 behaviour. 117851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 117951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static class SimpleFileLockTable extends FileLockTable { 118051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // synchronize on list for access 118151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final List<FileLock> lockList = new ArrayList<FileLock>(2); 118251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public SimpleFileLockTable() { 118451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 118551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 118651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private void checkList(long position, long size) 118751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws OverlappingFileLockException 118851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 118951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski assert Thread.holdsLock(lockList); 119051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski for (FileLock fl: lockList) { 119151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fl.overlaps(position, size)) { 119251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new OverlappingFileLockException(); 119351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 119651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 119751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void add(FileLock fl) throws OverlappingFileLockException { 119851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lockList) { 119951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski checkList(fl.position(), fl.size()); 120051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lockList.add(fl); 120151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 120451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void remove(FileLock fl) { 120551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lockList) { 120651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lockList.remove(fl); 120751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 120951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public List<FileLock> removeAll() { 121151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized(lockList) { 121251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski List<FileLock> result = new ArrayList<FileLock>(lockList); 121351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lockList.clear(); 121451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return result; 121551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 121651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 121751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 121851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void replace(FileLock fl1, FileLock fl2) { 121951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (lockList) { 122051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lockList.remove(fl1); 122151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski lockList.add(fl2); 122251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 122551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // -- Native methods -- 122751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 122851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Creates a new mapping 122951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private native long map0(int prot, long position, long length) 123051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws IOException; 123151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Removes an existing mapping 123351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native int unmap0(long address, long length); 123451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Transfers from src to dst, or returns -2 if kernel can't do that 1236519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera private native long transferTo0(FileDescriptor src, long position, 1237519adb2f61bb2bfa6cc993b1ca15cf7022b96697Shubham Ajmera long count, FileDescriptor dst); 123851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 123951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Sets or reports this file's position 124051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // If offset is -1, the current position is returned 124151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // otherwise the position is set to offset 124251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private native long position0(FileDescriptor fd, long offset); 124351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski // Caches fieldIDs 124551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private static native long initIDs(); 124651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 124751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski static { 124851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski allocationGranularity = initIDs(); 124951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 125051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 125151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 1252