src/share/classes/sun/nio/ch/FileChannelImpl.java

Print this page




 111         if (parent != null) {
 112 
 113             // Close the fd via the parent stream's close method.  The parent
 114             // will reinvoke our close method, which is defined in the
 115             // superclass AbstractInterruptibleChannel, but the isOpen logic in
 116             // that method will prevent this method from being reinvoked.
 117             //
 118             ((java.io.Closeable)parent).close();
 119         } else {
 120             nd.close(fd);
 121         }
 122 
 123     }
 124 
 125     public int read(ByteBuffer dst) throws IOException {
 126         ensureOpen();
 127         if (!readable)
 128             throw new NonReadableChannelException();
 129         synchronized (positionLock) {
 130             int n = 0;
 131             int ti = threads.add();
 132             try {
 133                 begin();

 134                 if (!isOpen())
 135                     return 0;
 136                 do {
 137                     n = IOUtil.read(fd, dst, -1, nd, positionLock);
 138                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 139                 return IOStatus.normalize(n);
 140             } finally {
 141                 threads.remove(ti);
 142                 end(n > 0);
 143                 assert IOStatus.check(n);
 144             }
 145         }
 146     }
 147 
 148     private long read0(ByteBuffer[] dsts) throws IOException {
 149         ensureOpen();
 150         if (!readable)
 151             throw new NonReadableChannelException();
 152         synchronized (positionLock) {
 153             long n = 0;
 154             int ti = threads.add();
 155             try {
 156                 begin();

 157                 if (!isOpen())
 158                     return 0;
 159                 do {
 160                     n = IOUtil.read(fd, dsts, nd);
 161                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 162                 return IOStatus.normalize(n);
 163             } finally {
 164                 threads.remove(ti);
 165                 end(n > 0);
 166                 assert IOStatus.check(n);
 167             }
 168         }
 169     }
 170 
 171     public long read(ByteBuffer[] dsts, int offset, int length)
 172         throws IOException
 173     {
 174         if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
 175            throw new IndexOutOfBoundsException();
 176         // ## Fix IOUtil.write so that we can avoid this array copy
 177         return read0(Util.subsequence(dsts, offset, length));
 178     }
 179 
 180     public int write(ByteBuffer src) throws IOException {
 181         ensureOpen();
 182         if (!writable)
 183             throw new NonWritableChannelException();
 184         synchronized (positionLock) {
 185             int n = 0;
 186             int ti = threads.add();
 187             try {
 188                 begin();

 189                 if (!isOpen())
 190                     return 0;
 191                 do {
 192                     n = IOUtil.write(fd, src, -1, nd, positionLock);
 193                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 194                 return IOStatus.normalize(n);
 195             } finally {
 196                 threads.remove(ti);
 197                 end(n > 0);
 198                 assert IOStatus.check(n);
 199             }
 200         }
 201     }
 202 
 203     private long write0(ByteBuffer[] srcs) throws IOException {
 204         ensureOpen();
 205         if (!writable)
 206             throw new NonWritableChannelException();
 207         synchronized (positionLock) {
 208             long n = 0;
 209             int ti = threads.add();
 210             try {
 211                 begin();

 212                 if (!isOpen())
 213                     return 0;
 214                 do {
 215                     n = IOUtil.write(fd, srcs, nd);
 216                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 217                 return IOStatus.normalize(n);
 218             } finally {
 219                 threads.remove(ti);
 220                 end(n > 0);
 221                 assert IOStatus.check(n);
 222             }
 223         }
 224     }
 225 
 226     public long write(ByteBuffer[] srcs, int offset, int length)
 227         throws IOException
 228     {
 229         if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
 230            throw new IndexOutOfBoundsException();
 231         // ## Fix IOUtil.write so that we can avoid this array copy
 232         return write0(Util.subsequence(srcs, offset, length));
 233     }
 234 
 235 
 236     // -- Other operations --
 237 
 238     public long position() throws IOException {
 239         ensureOpen();
 240         synchronized (positionLock) {
 241             long p = -1;
 242             int ti = threads.add();
 243             try {
 244                 begin();

 245                 if (!isOpen())
 246                     return 0;
 247                 do {
 248                     p = position0(fd, -1);
 249                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 250                 return IOStatus.normalize(p);
 251             } finally {
 252                 threads.remove(ti);
 253                 end(p > -1);
 254                 assert IOStatus.check(p);
 255             }
 256         }
 257     }
 258 
 259     public FileChannel position(long newPosition) throws IOException {
 260         ensureOpen();
 261         if (newPosition < 0)
 262             throw new IllegalArgumentException();
 263         synchronized (positionLock) {
 264             long p = -1;
 265             int ti = threads.add();
 266             try {
 267                 begin();

 268                 if (!isOpen())
 269                     return null;
 270                 do {
 271                     p  = position0(fd, newPosition);
 272                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 273                 return this;
 274             } finally {
 275                 threads.remove(ti);
 276                 end(p > -1);
 277                 assert IOStatus.check(p);
 278             }
 279         }
 280     }
 281 
 282     public long size() throws IOException {
 283         ensureOpen();
 284         synchronized (positionLock) {
 285             long s = -1;
 286             int ti = threads.add();
 287             try {
 288                 begin();

 289                 if (!isOpen())
 290                     return -1;
 291                 do {
 292                     s = nd.size(fd);
 293                 } while ((s == IOStatus.INTERRUPTED) && isOpen());
 294                 return IOStatus.normalize(s);
 295             } finally {
 296                 threads.remove(ti);
 297                 end(s > -1);
 298                 assert IOStatus.check(s);
 299             }
 300         }
 301     }
 302 
 303     public FileChannel truncate(long size) throws IOException {
 304         ensureOpen();
 305         if (size < 0)
 306             throw new IllegalArgumentException();
 307         if (size > size())
 308             return this;
 309         if (!writable)
 310             throw new NonWritableChannelException();
 311         synchronized (positionLock) {
 312             int rv = -1;
 313             long p = -1;
 314             int ti = threads.add();
 315             try {
 316                 begin();

 317                 if (!isOpen())
 318                     return null;
 319 
 320                 // get current position
 321                 do {
 322                     p = position0(fd, -1);
 323                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 324                 if (!isOpen())
 325                     return null;
 326                 assert p >= 0;
 327 
 328                 // truncate file
 329                 do {
 330                     rv = nd.truncate(fd, size);
 331                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 332                 if (!isOpen())
 333                     return null;
 334 
 335                 // set position to size if greater than size
 336                 if (p > size)
 337                     p = size;
 338                 do {
 339                     rv = (int)position0(fd, p);
 340                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 341                 return this;
 342             } finally {
 343                 threads.remove(ti);
 344                 end(rv > -1);
 345                 assert IOStatus.check(rv);
 346             }
 347         }
 348     }
 349 
 350     public void force(boolean metaData) throws IOException {
 351         ensureOpen();
 352         int rv = -1;
 353         int ti = threads.add();
 354         try {
 355             begin();

 356             if (!isOpen())
 357                 return;
 358             do {
 359                 rv = nd.force(fd, metaData);
 360             } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 361         } finally {
 362             threads.remove(ti);
 363             end(rv > -1);
 364             assert IOStatus.check(rv);
 365         }
 366     }
 367 
 368     // Assume at first that the underlying kernel supports sendfile();
 369     // set this to false if we find out later that it doesn't
 370     //
 371     private static volatile boolean transferSupported = true;
 372 
 373     // Assume that the underlying kernel sendfile() will work if the target
 374     // fd is a pipe; set this to false if we find out later that it doesn't
 375     //


 389 
 390         FileDescriptor targetFD = null;
 391         if (target instanceof FileChannelImpl) {
 392             if (!fileSupported)
 393                 return IOStatus.UNSUPPORTED_CASE;
 394             targetFD = ((FileChannelImpl)target).fd;
 395         } else if (target instanceof SelChImpl) {
 396             // Direct transfer to pipe causes EINVAL on some configurations
 397             if ((target instanceof SinkChannelImpl) && !pipeSupported)
 398                 return IOStatus.UNSUPPORTED_CASE;
 399             targetFD = ((SelChImpl)target).getFD();
 400         }
 401         if (targetFD == null)
 402             return IOStatus.UNSUPPORTED;
 403         int thisFDVal = IOUtil.fdVal(fd);
 404         int targetFDVal = IOUtil.fdVal(targetFD);
 405         if (thisFDVal == targetFDVal) // Not supported on some configurations
 406             return IOStatus.UNSUPPORTED;
 407 
 408         long n = -1;
 409         int ti = threads.add();
 410         try {
 411             begin();

 412             if (!isOpen())
 413                 return -1;
 414             do {
 415                 n = transferTo0(thisFDVal, position, icount, targetFDVal);
 416             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 417             if (n == IOStatus.UNSUPPORTED_CASE) {
 418                 if (target instanceof SinkChannelImpl)
 419                     pipeSupported = false;
 420                 if (target instanceof FileChannelImpl)
 421                     fileSupported = false;
 422                 return IOStatus.UNSUPPORTED_CASE;
 423             }
 424             if (n == IOStatus.UNSUPPORTED) {
 425                 // Don't bother trying again
 426                 transferSupported = false;
 427                 return IOStatus.UNSUPPORTED;
 428             }
 429             return IOStatus.normalize(n);
 430         } finally {
 431             threads.remove(ti);


 595         if ((position < 0) || (count < 0))
 596             throw new IllegalArgumentException();
 597         if (position > size())
 598             return 0;
 599         if (src instanceof FileChannelImpl)
 600            return transferFromFileChannel((FileChannelImpl)src,
 601                                           position, count);
 602 
 603         return transferFromArbitraryChannel(src, position, count);
 604     }
 605 
 606     public int read(ByteBuffer dst, long position) throws IOException {
 607         if (dst == null)
 608             throw new NullPointerException();
 609         if (position < 0)
 610             throw new IllegalArgumentException("Negative position");
 611         if (!readable)
 612             throw new NonReadableChannelException();
 613         ensureOpen();
 614         int n = 0;
 615         int ti = threads.add();
 616         try {
 617             begin();

 618             if (!isOpen())
 619                 return -1;
 620             do {
 621                 n = IOUtil.read(fd, dst, position, nd, positionLock);
 622             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 623             return IOStatus.normalize(n);
 624         } finally {
 625             threads.remove(ti);
 626             end(n > 0);
 627             assert IOStatus.check(n);
 628         }
 629     }
 630 
 631     public int write(ByteBuffer src, long position) throws IOException {
 632         if (src == null)
 633             throw new NullPointerException();
 634         if (position < 0)
 635             throw new IllegalArgumentException("Negative position");
 636         if (!writable)
 637             throw new NonWritableChannelException();
 638         ensureOpen();
 639         int n = 0;
 640         int ti = threads.add();
 641         try {
 642             begin();

 643             if (!isOpen())
 644                 return -1;
 645             do {
 646                 n = IOUtil.write(fd, src, position, nd, positionLock);
 647             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 648             return IOStatus.normalize(n);
 649         } finally {
 650             threads.remove(ti);
 651             end(n > 0);
 652             assert IOStatus.check(n);
 653         }
 654     }
 655 
 656 
 657     // -- Memory-mapped buffers --
 658 
 659     private static class Unmapper
 660         implements Runnable
 661     {
 662         // keep track of mapped buffer usage


 714         if (size < 0L)
 715             throw new IllegalArgumentException("Negative size");
 716         if (position + size < 0)
 717             throw new IllegalArgumentException("Position + size overflow");
 718         if (size > Integer.MAX_VALUE)
 719             throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
 720         int imode = -1;
 721         if (mode == MapMode.READ_ONLY)
 722             imode = MAP_RO;
 723         else if (mode == MapMode.READ_WRITE)
 724             imode = MAP_RW;
 725         else if (mode == MapMode.PRIVATE)
 726             imode = MAP_PV;
 727         assert (imode >= 0);
 728         if ((mode != MapMode.READ_ONLY) && !writable)
 729             throw new NonWritableChannelException();
 730         if (!readable)
 731             throw new NonReadableChannelException();
 732 
 733         long addr = -1;
 734         int ti = threads.add();
 735         try {
 736             begin();

 737             if (!isOpen())
 738                 return null;
 739             if (size() < position + size) { // Extend file size
 740                 if (!writable) {
 741                     throw new IOException("Channel not open for writing " +
 742                         "- cannot extend file to required size");
 743                 }
 744                 int rv;
 745                 do {
 746                     rv = nd.truncate(fd, position + size);
 747                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 748             }
 749             if (size == 0) {
 750                 addr = 0;
 751                 if ((!writable) || (imode == MAP_RO))
 752                     return Util.newMappedByteBufferR(0, 0, null);
 753                 else
 754                     return Util.newMappedByteBuffer(0, 0, null);
 755             }
 756 


 883                         fileLockTable = new SimpleFileLockTable();
 884                     }
 885                 }
 886             }
 887         }
 888         return fileLockTable;
 889     }
 890 
 891     public FileLock lock(long position, long size, boolean shared)
 892         throws IOException
 893     {
 894         ensureOpen();
 895         if (shared && !readable)
 896             throw new NonReadableChannelException();
 897         if (!shared && !writable)
 898             throw new NonWritableChannelException();
 899         FileLockImpl fli = new FileLockImpl(this, position, size, shared);
 900         FileLockTable flt = fileLockTable();
 901         flt.add(fli);
 902         boolean i = true;
 903         int ti = threads.add();
 904         try {
 905             begin();

 906             if (!isOpen())
 907                 return null;
 908             int result = nd.lock(fd, true, position, size, shared);
 909             if (result == FileDispatcher.RET_EX_LOCK) {
 910                 assert shared;
 911                 FileLockImpl fli2 = new FileLockImpl(this, position, size,
 912                                                      false);
 913                 flt.replace(fli, fli2);
 914                 return fli2;
 915             }
 916             if (result == FileDispatcher.INTERRUPTED || result == FileDispatcher.NO_LOCK) {
 917                 flt.remove(fli);
 918                 i = false;
 919             }
 920         } catch (IOException e) {
 921             flt.remove(fli);
 922             throw e;
 923         } finally {
 924             threads.remove(ti);
 925             try {




 111         if (parent != null) {
 112 
 113             // Close the fd via the parent stream's close method.  The parent
 114             // will reinvoke our close method, which is defined in the
 115             // superclass AbstractInterruptibleChannel, but the isOpen logic in
 116             // that method will prevent this method from being reinvoked.
 117             //
 118             ((java.io.Closeable)parent).close();
 119         } else {
 120             nd.close(fd);
 121         }
 122 
 123     }
 124 
 125     public int read(ByteBuffer dst) throws IOException {
 126         ensureOpen();
 127         if (!readable)
 128             throw new NonReadableChannelException();
 129         synchronized (positionLock) {
 130             int n = 0;
 131             int ti = -1;
 132             try {
 133                 begin();
 134                 ti = threads.add();
 135                 if (!isOpen())
 136                     return 0;
 137                 do {
 138                     n = IOUtil.read(fd, dst, -1, nd, positionLock);
 139                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 140                 return IOStatus.normalize(n);
 141             } finally {
 142                 threads.remove(ti);
 143                 end(n > 0);
 144                 assert IOStatus.check(n);
 145             }
 146         }
 147     }
 148 
 149     private long read0(ByteBuffer[] dsts) throws IOException {
 150         ensureOpen();
 151         if (!readable)
 152             throw new NonReadableChannelException();
 153         synchronized (positionLock) {
 154             long n = 0;
 155             int ti = -1;
 156             try {
 157                 begin();
 158                 ti = threads.add();
 159                 if (!isOpen())
 160                     return 0;
 161                 do {
 162                     n = IOUtil.read(fd, dsts, nd);
 163                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 164                 return IOStatus.normalize(n);
 165             } finally {
 166                 threads.remove(ti);
 167                 end(n > 0);
 168                 assert IOStatus.check(n);
 169             }
 170         }
 171     }
 172 
 173     public long read(ByteBuffer[] dsts, int offset, int length)
 174         throws IOException
 175     {
 176         if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
 177            throw new IndexOutOfBoundsException();
 178         // ## Fix IOUtil.write so that we can avoid this array copy
 179         return read0(Util.subsequence(dsts, offset, length));
 180     }
 181 
 182     public int write(ByteBuffer src) throws IOException {
 183         ensureOpen();
 184         if (!writable)
 185             throw new NonWritableChannelException();
 186         synchronized (positionLock) {
 187             int n = 0;
 188             int ti = -1;
 189             try {
 190                 begin();
 191                 ti = threads.add();
 192                 if (!isOpen())
 193                     return 0;
 194                 do {
 195                     n = IOUtil.write(fd, src, -1, nd, positionLock);
 196                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 197                 return IOStatus.normalize(n);
 198             } finally {
 199                 threads.remove(ti);
 200                 end(n > 0);
 201                 assert IOStatus.check(n);
 202             }
 203         }
 204     }
 205 
 206     private long write0(ByteBuffer[] srcs) throws IOException {
 207         ensureOpen();
 208         if (!writable)
 209             throw new NonWritableChannelException();
 210         synchronized (positionLock) {
 211             long n = 0;
 212             int ti = -1;
 213             try {
 214                 begin();
 215                 ti = threads.add();
 216                 if (!isOpen())
 217                     return 0;
 218                 do {
 219                     n = IOUtil.write(fd, srcs, nd);
 220                 } while ((n == IOStatus.INTERRUPTED) && isOpen());
 221                 return IOStatus.normalize(n);
 222             } finally {
 223                 threads.remove(ti);
 224                 end(n > 0);
 225                 assert IOStatus.check(n);
 226             }
 227         }
 228     }
 229 
 230     public long write(ByteBuffer[] srcs, int offset, int length)
 231         throws IOException
 232     {
 233         if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
 234            throw new IndexOutOfBoundsException();
 235         // ## Fix IOUtil.write so that we can avoid this array copy
 236         return write0(Util.subsequence(srcs, offset, length));
 237     }
 238 
 239 
 240     // -- Other operations --
 241 
 242     public long position() throws IOException {
 243         ensureOpen();
 244         synchronized (positionLock) {
 245             long p = -1;
 246             int ti = -1;
 247             try {
 248                 begin();
 249                 ti = threads.add();
 250                 if (!isOpen())
 251                     return 0;
 252                 do {
 253                     p = position0(fd, -1);
 254                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 255                 return IOStatus.normalize(p);
 256             } finally {
 257                 threads.remove(ti);
 258                 end(p > -1);
 259                 assert IOStatus.check(p);
 260             }
 261         }
 262     }
 263 
 264     public FileChannel position(long newPosition) throws IOException {
 265         ensureOpen();
 266         if (newPosition < 0)
 267             throw new IllegalArgumentException();
 268         synchronized (positionLock) {
 269             long p = -1;
 270             int ti = -1;
 271             try {
 272                 begin();
 273                 ti = threads.add();
 274                 if (!isOpen())
 275                     return null;
 276                 do {
 277                     p  = position0(fd, newPosition);
 278                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 279                 return this;
 280             } finally {
 281                 threads.remove(ti);
 282                 end(p > -1);
 283                 assert IOStatus.check(p);
 284             }
 285         }
 286     }
 287 
 288     public long size() throws IOException {
 289         ensureOpen();
 290         synchronized (positionLock) {
 291             long s = -1;
 292             int ti = -1;
 293             try {
 294                 begin();
 295                 ti = threads.add();
 296                 if (!isOpen())
 297                     return -1;
 298                 do {
 299                     s = nd.size(fd);
 300                 } while ((s == IOStatus.INTERRUPTED) && isOpen());
 301                 return IOStatus.normalize(s);
 302             } finally {
 303                 threads.remove(ti);
 304                 end(s > -1);
 305                 assert IOStatus.check(s);
 306             }
 307         }
 308     }
 309 
 310     public FileChannel truncate(long size) throws IOException {
 311         ensureOpen();
 312         if (size < 0)
 313             throw new IllegalArgumentException();
 314         if (size > size())
 315             return this;
 316         if (!writable)
 317             throw new NonWritableChannelException();
 318         synchronized (positionLock) {
 319             int rv = -1;
 320             long p = -1;
 321             int ti = -1;
 322             try {
 323                 begin();
 324                 ti = threads.add();
 325                 if (!isOpen())
 326                     return null;
 327 
 328                 // get current position
 329                 do {
 330                     p = position0(fd, -1);
 331                 } while ((p == IOStatus.INTERRUPTED) && isOpen());
 332                 if (!isOpen())
 333                     return null;
 334                 assert p >= 0;
 335 
 336                 // truncate file
 337                 do {
 338                     rv = nd.truncate(fd, size);
 339                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 340                 if (!isOpen())
 341                     return null;
 342 
 343                 // set position to size if greater than size
 344                 if (p > size)
 345                     p = size;
 346                 do {
 347                     rv = (int)position0(fd, p);
 348                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 349                 return this;
 350             } finally {
 351                 threads.remove(ti);
 352                 end(rv > -1);
 353                 assert IOStatus.check(rv);
 354             }
 355         }
 356     }
 357 
 358     public void force(boolean metaData) throws IOException {
 359         ensureOpen();
 360         int rv = -1;
 361         int ti = -1;
 362         try {
 363             begin();
 364             ti = threads.add();
 365             if (!isOpen())
 366                 return;
 367             do {
 368                 rv = nd.force(fd, metaData);
 369             } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 370         } finally {
 371             threads.remove(ti);
 372             end(rv > -1);
 373             assert IOStatus.check(rv);
 374         }
 375     }
 376 
 377     // Assume at first that the underlying kernel supports sendfile();
 378     // set this to false if we find out later that it doesn't
 379     //
 380     private static volatile boolean transferSupported = true;
 381 
 382     // Assume that the underlying kernel sendfile() will work if the target
 383     // fd is a pipe; set this to false if we find out later that it doesn't
 384     //


 398 
 399         FileDescriptor targetFD = null;
 400         if (target instanceof FileChannelImpl) {
 401             if (!fileSupported)
 402                 return IOStatus.UNSUPPORTED_CASE;
 403             targetFD = ((FileChannelImpl)target).fd;
 404         } else if (target instanceof SelChImpl) {
 405             // Direct transfer to pipe causes EINVAL on some configurations
 406             if ((target instanceof SinkChannelImpl) && !pipeSupported)
 407                 return IOStatus.UNSUPPORTED_CASE;
 408             targetFD = ((SelChImpl)target).getFD();
 409         }
 410         if (targetFD == null)
 411             return IOStatus.UNSUPPORTED;
 412         int thisFDVal = IOUtil.fdVal(fd);
 413         int targetFDVal = IOUtil.fdVal(targetFD);
 414         if (thisFDVal == targetFDVal) // Not supported on some configurations
 415             return IOStatus.UNSUPPORTED;
 416 
 417         long n = -1;
 418         int ti = -1;
 419         try {
 420             begin();
 421             ti = threads.add();
 422             if (!isOpen())
 423                 return -1;
 424             do {
 425                 n = transferTo0(thisFDVal, position, icount, targetFDVal);
 426             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 427             if (n == IOStatus.UNSUPPORTED_CASE) {
 428                 if (target instanceof SinkChannelImpl)
 429                     pipeSupported = false;
 430                 if (target instanceof FileChannelImpl)
 431                     fileSupported = false;
 432                 return IOStatus.UNSUPPORTED_CASE;
 433             }
 434             if (n == IOStatus.UNSUPPORTED) {
 435                 // Don't bother trying again
 436                 transferSupported = false;
 437                 return IOStatus.UNSUPPORTED;
 438             }
 439             return IOStatus.normalize(n);
 440         } finally {
 441             threads.remove(ti);


 605         if ((position < 0) || (count < 0))
 606             throw new IllegalArgumentException();
 607         if (position > size())
 608             return 0;
 609         if (src instanceof FileChannelImpl)
 610            return transferFromFileChannel((FileChannelImpl)src,
 611                                           position, count);
 612 
 613         return transferFromArbitraryChannel(src, position, count);
 614     }
 615 
 616     public int read(ByteBuffer dst, long position) throws IOException {
 617         if (dst == null)
 618             throw new NullPointerException();
 619         if (position < 0)
 620             throw new IllegalArgumentException("Negative position");
 621         if (!readable)
 622             throw new NonReadableChannelException();
 623         ensureOpen();
 624         int n = 0;
 625         int ti = -1;
 626         try {
 627             begin();
 628             ti = threads.add();
 629             if (!isOpen())
 630                 return -1;
 631             do {
 632                 n = IOUtil.read(fd, dst, position, nd, positionLock);
 633             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 634             return IOStatus.normalize(n);
 635         } finally {
 636             threads.remove(ti);
 637             end(n > 0);
 638             assert IOStatus.check(n);
 639         }
 640     }
 641 
 642     public int write(ByteBuffer src, long position) throws IOException {
 643         if (src == null)
 644             throw new NullPointerException();
 645         if (position < 0)
 646             throw new IllegalArgumentException("Negative position");
 647         if (!writable)
 648             throw new NonWritableChannelException();
 649         ensureOpen();
 650         int n = 0;
 651         int ti = -1;
 652         try {
 653             begin();
 654             ti = threads.add();
 655             if (!isOpen())
 656                 return -1;
 657             do {
 658                 n = IOUtil.write(fd, src, position, nd, positionLock);
 659             } while ((n == IOStatus.INTERRUPTED) && isOpen());
 660             return IOStatus.normalize(n);
 661         } finally {
 662             threads.remove(ti);
 663             end(n > 0);
 664             assert IOStatus.check(n);
 665         }
 666     }
 667 
 668 
 669     // -- Memory-mapped buffers --
 670 
 671     private static class Unmapper
 672         implements Runnable
 673     {
 674         // keep track of mapped buffer usage


 726         if (size < 0L)
 727             throw new IllegalArgumentException("Negative size");
 728         if (position + size < 0)
 729             throw new IllegalArgumentException("Position + size overflow");
 730         if (size > Integer.MAX_VALUE)
 731             throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
 732         int imode = -1;
 733         if (mode == MapMode.READ_ONLY)
 734             imode = MAP_RO;
 735         else if (mode == MapMode.READ_WRITE)
 736             imode = MAP_RW;
 737         else if (mode == MapMode.PRIVATE)
 738             imode = MAP_PV;
 739         assert (imode >= 0);
 740         if ((mode != MapMode.READ_ONLY) && !writable)
 741             throw new NonWritableChannelException();
 742         if (!readable)
 743             throw new NonReadableChannelException();
 744 
 745         long addr = -1;
 746         int ti = -1;
 747         try {
 748             begin();
 749             ti = threads.add();
 750             if (!isOpen())
 751                 return null;
 752             if (size() < position + size) { // Extend file size
 753                 if (!writable) {
 754                     throw new IOException("Channel not open for writing " +
 755                         "- cannot extend file to required size");
 756                 }
 757                 int rv;
 758                 do {
 759                     rv = nd.truncate(fd, position + size);
 760                 } while ((rv == IOStatus.INTERRUPTED) && isOpen());
 761             }
 762             if (size == 0) {
 763                 addr = 0;
 764                 if ((!writable) || (imode == MAP_RO))
 765                     return Util.newMappedByteBufferR(0, 0, null);
 766                 else
 767                     return Util.newMappedByteBuffer(0, 0, null);
 768             }
 769 


 896                         fileLockTable = new SimpleFileLockTable();
 897                     }
 898                 }
 899             }
 900         }
 901         return fileLockTable;
 902     }
 903 
 904     public FileLock lock(long position, long size, boolean shared)
 905         throws IOException
 906     {
 907         ensureOpen();
 908         if (shared && !readable)
 909             throw new NonReadableChannelException();
 910         if (!shared && !writable)
 911             throw new NonWritableChannelException();
 912         FileLockImpl fli = new FileLockImpl(this, position, size, shared);
 913         FileLockTable flt = fileLockTable();
 914         flt.add(fli);
 915         boolean i = true;
 916         int ti = -1;
 917         try {
 918             begin();
 919             ti = threads.add();
 920             if (!isOpen())
 921                 return null;
 922             int result = nd.lock(fd, true, position, size, shared);
 923             if (result == FileDispatcher.RET_EX_LOCK) {
 924                 assert shared;
 925                 FileLockImpl fli2 = new FileLockImpl(this, position, size,
 926                                                      false);
 927                 flt.replace(fli, fli2);
 928                 return fli2;
 929             }
 930             if (result == FileDispatcher.INTERRUPTED || result == FileDispatcher.NO_LOCK) {
 931                 flt.remove(fli);
 932                 i = false;
 933             }
 934         } catch (IOException e) {
 935             flt.remove(fli);
 936             throw e;
 937         } finally {
 938             threads.remove(ti);
 939             try {