< prev index next >

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

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -45,26 +45,42 @@
 
     static int write(FileDescriptor fd, ByteBuffer src, long position,
                      NativeDispatcher nd)
         throws IOException
     {
-        if (src instanceof DirectBuffer)
-            return writeFromNativeBuffer(fd, src, position, nd);
+        return write(fd, src, position, false, -1, nd);
+    }
+
+    static int write(FileDescriptor fd, ByteBuffer src, long position,
+                     boolean directIO, int alignment, NativeDispatcher nd)
+        throws IOException
+    {
+        if (src instanceof DirectBuffer) {
+            return writeFromNativeBuffer(fd, src, position,
+                                         directIO, alignment, nd);
+        }
 
         // Substitute a native buffer
         int pos = src.position();
         int lim = src.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
-        ByteBuffer bb = Util.getTemporaryDirectBuffer(rem);
+        ByteBuffer bb;
+        if (directIO) {
+            Util.checkRemainingBufferSizeAligned(rem, alignment);
+            bb = Util.getTemporaryAlignedDirectBuffer(rem, alignment);
+        } else {
+            bb = Util.getTemporaryDirectBuffer(rem);
+        }
         try {
             bb.put(src);
             bb.flip();
             // Do not update src until we see how many bytes were written
             src.position(pos);
 
-            int n = writeFromNativeBuffer(fd, bb, position, nd);
+            int n = writeFromNativeBuffer(fd, bb, position,
+                    directIO, alignment, nd);
             if (n > 0) {
                 // now update src
                 src.position(pos + n);
             }
             return n;

@@ -72,18 +88,24 @@
             Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
     private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
-                                             long position, NativeDispatcher nd)
+                                             long position, boolean directIO,
+                                             int alignment, NativeDispatcher nd)
         throws IOException
     {
         int pos = bb.position();
         int lim = bb.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
 
+        if (directIO) {
+            Util.checkBufferPositionAligned(bb, pos, alignment);
+            Util.checkRemainingBufferSizeAligned(rem, alignment);
+        }
+
         int written = 0;
         if (rem == 0)
             return 0;
         if (position != -1) {
             written = nd.pwrite(fd,

@@ -98,17 +120,24 @@
     }
 
     static long write(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        return write(fd, bufs, 0, bufs.length, nd);
+        return write(fd, bufs, 0, bufs.length, false, -1, nd);
     }
 
     static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
                       NativeDispatcher nd)
         throws IOException
     {
+        return write(fd, bufs, offset, length, false, -1, nd);
+    }
+
+    static long write(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                      boolean directIO, int alignment, NativeDispatcher nd)
+        throws IOException
+    {
         IOVecWrapper vec = IOVecWrapper.get(length);
 
         boolean completed = false;
         int iov_len = 0;
         try {

@@ -120,16 +149,24 @@
                 ByteBuffer buf = bufs[i];
                 int pos = buf.position();
                 int lim = buf.limit();
                 assert (pos <= lim);
                 int rem = (pos <= lim ? lim - pos : 0);
+                if (directIO)
+                    Util.checkRemainingBufferSizeAligned(rem, alignment);
+
                 if (rem > 0) {
                     vec.setBuffer(iov_len, buf, pos, rem);
 
                     // allocate shadow buffer to ensure I/O is done with direct buffer
                     if (!(buf instanceof DirectBuffer)) {
-                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        ByteBuffer shadow;
+                        if (directIO)
+                            shadow = Util.getTemporaryAlignedDirectBuffer(rem,
+                                    alignment);
+                        else
+                            shadow = Util.getTemporaryDirectBuffer(rem);
                         shadow.put(buf);
                         shadow.flip();
                         vec.setShadow(iov_len, shadow);
                         buf.position(pos);  // temporarily restore position in user buffer
                         buf = shadow;

@@ -184,37 +221,60 @@
 
     static int read(FileDescriptor fd, ByteBuffer dst, long position,
                     NativeDispatcher nd)
         throws IOException
     {
+        return read(fd, dst, position, false, -1, nd);
+    }
+
+    static int read(FileDescriptor fd, ByteBuffer dst, long position,
+                    boolean directIO, int alignment, NativeDispatcher nd)
+        throws IOException
+    {
         if (dst.isReadOnly())
             throw new IllegalArgumentException("Read-only buffer");
         if (dst instanceof DirectBuffer)
-            return readIntoNativeBuffer(fd, dst, position, nd);
+            return readIntoNativeBuffer(fd, dst, position,
+                    directIO, alignment, nd);
 
         // Substitute a native buffer
-        ByteBuffer bb = Util.getTemporaryDirectBuffer(dst.remaining());
+        ByteBuffer bb;
+        int rem = dst.remaining();
+        if (directIO) {
+            Util.checkRemainingBufferSizeAligned(rem, alignment);
+            bb = Util.getTemporaryAlignedDirectBuffer(rem,
+                                                      alignment);
+        } else {
+            bb = Util.getTemporaryDirectBuffer(rem);
+        }
         try {
-            int n = readIntoNativeBuffer(fd, bb, position, nd);
+            int n = readIntoNativeBuffer(fd, bb, position,
+                    directIO, alignment,nd);
             bb.flip();
             if (n > 0)
                 dst.put(bb);
             return n;
         } finally {
             Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
     private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb,
-                                            long position, NativeDispatcher nd)
+                                            long position, boolean directIO,
+                                            int alignment, NativeDispatcher nd)
         throws IOException
     {
         int pos = bb.position();
         int lim = bb.limit();
         assert (pos <= lim);
         int rem = (pos <= lim ? lim - pos : 0);
 
+        if (directIO) {
+            Util.checkBufferPositionAligned(bb, pos, alignment);
+            Util.checkRemainingBufferSizeAligned(rem, alignment);
+        }
+
         if (rem == 0)
             return 0;
         int n = 0;
         if (position != -1) {
             n = nd.pread(fd, ((DirectBuffer)bb).address() + pos,

@@ -228,17 +288,24 @@
     }
 
     static long read(FileDescriptor fd, ByteBuffer[] bufs, NativeDispatcher nd)
         throws IOException
     {
-        return read(fd, bufs, 0, bufs.length, nd);
+        return read(fd, bufs, 0, bufs.length, false, -1, nd);
     }
 
     static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
                      NativeDispatcher nd)
         throws IOException
     {
+        return read(fd, bufs, offset, bufs.length, false, -1, nd);
+    }
+
+    static long read(FileDescriptor fd, ByteBuffer[] bufs, int offset, int length,
+                     boolean directIO, int alignment, NativeDispatcher nd)
+        throws IOException
+    {
         IOVecWrapper vec = IOVecWrapper.get(length);
 
         boolean completed = false;
         int iov_len = 0;
         try {

@@ -253,16 +320,25 @@
                 int pos = buf.position();
                 int lim = buf.limit();
                 assert (pos <= lim);
                 int rem = (pos <= lim ? lim - pos : 0);
 
+                if (directIO)
+                    Util.checkRemainingBufferSizeAligned(rem, alignment);
+
                 if (rem > 0) {
                     vec.setBuffer(iov_len, buf, pos, rem);
 
                     // allocate shadow buffer to ensure I/O is done with direct buffer
                     if (!(buf instanceof DirectBuffer)) {
-                        ByteBuffer shadow = Util.getTemporaryDirectBuffer(rem);
+                        ByteBuffer shadow;
+                        if (directIO) {
+                            shadow = Util.getTemporaryAlignedDirectBuffer(rem,
+                                    alignment);
+                        } else {
+                            shadow = Util.getTemporaryDirectBuffer(rem);
+                        }
                         vec.setShadow(iov_len, shadow);
                         buf = shadow;
                         pos = shadow.position();
                     }
 
< prev index next >