1e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera/* 2e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. 3e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 5e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is free software; you can redistribute it and/or modify it 6e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * under the terms of the GNU General Public License version 2 only, as 7e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * published by the Free Software Foundation. Oracle designates this 8e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * particular file as subject to the "Classpath" exception as provided 9e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * by Oracle in the LICENSE file that accompanied this code. 10e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 11e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * This code is distributed in the hope that it will be useful, but WITHOUT 12e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * version 2 for more details (a copy is included in the LICENSE file that 15e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * accompanied this code). 16e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 17e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * You should have received a copy of the GNU General Public License version 18e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 2 along with this work; if not, write to the Free Software Foundation, 19e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * 21e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * or visit www.oracle.com if you need additional information or have any 23e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * questions. 24e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 25e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 26e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmerapackage sun.nio.ch; 27e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 28e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.channels.*; 29e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.util.concurrent.*; 30e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.nio.ByteBuffer; 31e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.security.AccessController; 32e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.security.PrivilegedAction; 33e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.io.FileDescriptor; 34e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmeraimport java.io.IOException; 35e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 36e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera/** 37e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * "Portable" implementation of AsynchronousFileChannel for use on operating 38e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera * systems that don't support asynchronous file I/O. 39e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera */ 40e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 41e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmerapublic class SimpleAsynchronousFileChannelImpl 42e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera extends AsynchronousFileChannelImpl 43e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera{ 44e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // lazy initialization of default thread pool for file I/O 45e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static class DefaultExecutorHolder { 46e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera static final ExecutorService defaultExecutor = 47e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera ThreadPool.createDefault().executor(); 48e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 49e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 50e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // Used to make native read and write calls 51e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private static final FileDispatcher nd = new FileDispatcherImpl(); 52e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 53e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // Thread-safe set of IDs of native threads, for signalling 54e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera private final NativeThreadSet threads = new NativeThreadSet(2); 55e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 56e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 57e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj, 58e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean reading, 59e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean writing, 60e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera ExecutorService executor) 61e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 62e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera super(fdObj, reading, writing, executor); 63e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 64e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 65e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public static AsynchronousFileChannel open(FileDescriptor fdo, 66e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean reading, 67e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean writing, 68e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera ThreadPool pool) 69e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 70e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // Executor is either default or based on pool parameters 71e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera ExecutorService executor = (pool == null) ? 72e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera DefaultExecutorHolder.defaultExecutor : pool.executor(); 73e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor); 74e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 75e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 76e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 77e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public void close() throws IOException { 78e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // mark channel as closed 79e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera synchronized (fdObj) { 80e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (closed) 81e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return; // already closed 82e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera closed = true; 83e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // from this point on, if another thread invokes the begin() method 84e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // then it will throw ClosedChannelException 85e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 86e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 87e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // Invalidate and release any locks that we still hold 88e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera invalidateAllLocks(); 89e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 90e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // signal any threads blocked on this channel 91e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.signalAndWait(); 92e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 93e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // wait until all async I/O operations have completely gracefully 94e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera closeLock.writeLock().lock(); 95e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 96e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // do nothing 97e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 98e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera closeLock.writeLock().unlock(); 99e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 100e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 101e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // close file 102e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera nd.close(fdObj); 103e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 104e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 105e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 106e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public long size() throws IOException { 107e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 108e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 109e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera long n = 0L; 110e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 111e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 112e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 113e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.size(fdObj); 114e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 115e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return n; 116e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 117e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(n >= 0L); 118e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 119e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 120e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 121e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 122e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 123e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 124e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 125e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public AsynchronousFileChannel truncate(long size) throws IOException { 126e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (size < 0L) 127e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new IllegalArgumentException("Negative size"); 128e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!writing) 129e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonWritableChannelException(); 130e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 131e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 132e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera long n = 0L; 133e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 134e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 135e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 136e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.size(fdObj); 137e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 138e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 139e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // truncate file if 'size' less than current size 140e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (size < n && isOpen()) { 141e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 142e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.truncate(fdObj, size); 143e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 144e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 145e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return this; 146e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 147e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(n > 0); 148e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 149e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 150e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 151e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 152e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 153e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 154e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 155e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public void force(boolean metaData) throws IOException { 156e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 157e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 158e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int n = 0; 159e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 160e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 161e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 162e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.force(fdObj, metaData); 163e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 164e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 165e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(n >= 0); 166e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 167e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 168e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 169e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 170e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 171e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 172e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 173e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera <A> Future<FileLock> implLock(final long position, 174e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final long size, 175e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final boolean shared, 176e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final A attachment, 177e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final CompletionHandler<FileLock,? super A> handler) 178e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 179e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (shared && !reading) 180e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonReadableChannelException(); 181e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!shared && !writing) 182e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonWritableChannelException(); 183e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 184e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // add to lock table 185e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final FileLockImpl fli = addToFileLockTable(position, size, shared); 186e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (fli == null) { 187e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = new ClosedChannelException(); 188e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) 189e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return CompletedFuture.withFailure(exc); 190e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeIndirectly(handler, attachment, null, exc, executor); 191e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; 192e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 193e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 194e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final PendingFuture<FileLock,A> result = (handler == null) ? 195e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera new PendingFuture<FileLock,A>(this) : null; 196e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Runnable task = new Runnable() { 197e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public void run() { 198e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = null; 199e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 200e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 201e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 202e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int n; 203e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 204e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 205e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 206e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.lock(fdObj, true, position, size, shared); 207e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == FileDispatcher.INTERRUPTED) && isOpen()); 208e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n != FileDispatcher.LOCKED || !isOpen()) { 209e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new AsynchronousCloseException(); 210e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 211e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } catch (IOException x) { 212e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera removeFromFileLockTable(fli); 213e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isOpen()) 214e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera x = new AsynchronousCloseException(); 215e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera exc = x; 216e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 217e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(); 218e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 219e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 220e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 221e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 222e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) { 223e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera result.setResult(fli, exc); 224e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } else { 225e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeUnchecked(handler, attachment, fli, exc); 226e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 227e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 228e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera }; 229e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean executed = false; 230e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 231e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera executor.execute(task); 232e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera executed = true; 233e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 234e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!executed) { 235e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // rollback 236e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera removeFromFileLockTable(fli); 237e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 238e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 239e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return result; 240e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 241e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 242e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 243e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public FileLock tryLock(long position, long size, boolean shared) 244e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throws IOException 245e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 246e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (shared && !reading) 247e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonReadableChannelException(); 248e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!shared && !writing) 249e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonWritableChannelException(); 250e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 251e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // add to lock table 252e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera FileLockImpl fli = addToFileLockTable(position, size, shared); 253e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (fli == null) 254e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new ClosedChannelException(); 255e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 256e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 257e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera boolean gotLock = false; 258e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 259e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 260e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int n; 261e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 262e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = nd.lock(fdObj, false, position, size, shared); 263e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == FileDispatcher.INTERRUPTED) && isOpen()); 264e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n == FileDispatcher.LOCKED && isOpen()) { 265e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera gotLock = true; 266e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return fli; // lock acquired 267e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 268e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n == FileDispatcher.NO_LOCK) 269e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; // locked by someone else 270e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n == FileDispatcher.INTERRUPTED) 271e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new AsynchronousCloseException(); 272e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // should not get here 273e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new AssertionError(); 274e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 275e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!gotLock) 276e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera removeFromFileLockTable(fli); 277e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(); 278e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 279e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 280e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 281e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 282e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 283e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera protected void implRelease(FileLockImpl fli) throws IOException { 284e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera nd.release(fdObj, fli.position(), fli.size()); 285e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 286e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 287e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 288e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera <A> Future<Integer> implRead(final ByteBuffer dst, 289e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final long position, 290e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final A attachment, 291e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final CompletionHandler<Integer,? super A> handler) 292e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 293e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (position < 0) 294e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new IllegalArgumentException("Negative position"); 295e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!reading) 296e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonReadableChannelException(); 297e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (dst.isReadOnly()) 298e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new IllegalArgumentException("Read-only buffer"); 299e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 300e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // complete immediately if channel closed or no space remaining 301e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isOpen() || (dst.remaining() == 0)) { 302e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = (isOpen()) ? null : new ClosedChannelException(); 303e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) 304e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return CompletedFuture.withResult(0, exc); 305e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeIndirectly(handler, attachment, 0, exc, executor); 306e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; 307e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 308e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 309e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final PendingFuture<Integer,A> result = (handler == null) ? 310e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera new PendingFuture<Integer,A>(this) : null; 311e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Runnable task = new Runnable() { 312e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public void run() { 313e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int n = 0; 314e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = null; 315e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 316e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 317e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 318e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 319e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 320e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = IOUtil.read(fdObj, dst, position, nd); 321e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 322e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n < 0 && !isOpen()) 323e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new AsynchronousCloseException(); 324e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } catch (IOException x) { 325e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isOpen()) 326e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera x = new AsynchronousCloseException(); 327e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera exc = x; 328e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 329e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(); 330e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 331e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 332e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) { 333e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera result.setResult(n, exc); 334e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } else { 335e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeUnchecked(handler, attachment, n, exc); 336e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 337e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 338e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera }; 339e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera executor.execute(task); 340e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return result; 341e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 342e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 343e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera @Override 344e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera <A> Future<Integer> implWrite(final ByteBuffer src, 345e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final long position, 346e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final A attachment, 347e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final CompletionHandler<Integer,? super A> handler) 348e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera { 349e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (position < 0) 350e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new IllegalArgumentException("Negative position"); 351e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!writing) 352e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new NonWritableChannelException(); 353e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 354e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera // complete immediately if channel is closed or no bytes remaining 355e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isOpen() || (src.remaining() == 0)) { 356e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = (isOpen()) ? null : new ClosedChannelException(); 357e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) 358e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return CompletedFuture.withResult(0, exc); 359e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeIndirectly(handler, attachment, 0, exc, executor); 360e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return null; 361e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 362e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 363e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera final PendingFuture<Integer,A> result = (handler == null) ? 364e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera new PendingFuture<Integer,A>(this) : null; 365e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Runnable task = new Runnable() { 366e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera public void run() { 367e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int n = 0; 368e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Throwable exc = null; 369e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera 370e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera int ti = threads.add(); 371e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera try { 372e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera begin(); 373e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera do { 374e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera n = IOUtil.write(fdObj, src, position, nd); 375e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } while ((n == IOStatus.INTERRUPTED) && isOpen()); 376e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (n < 0 && !isOpen()) 377e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera throw new AsynchronousCloseException(); 378e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } catch (IOException x) { 379e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (!isOpen()) 380e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera x = new AsynchronousCloseException(); 381e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera exc = x; 382e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } finally { 383e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera end(); 384e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera threads.remove(ti); 385e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 386e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera if (handler == null) { 387e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera result.setResult(n, exc); 388e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } else { 389e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera Invoker.invokeUnchecked(handler, attachment, n, exc); 390e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 391e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 392e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera }; 393e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera executor.execute(task); 394e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera return result; 395e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera } 396e6bac4bf9c85c2454ce22c91da6c654552c268e0Shubham Ajmera} 397