< prev index next >

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

Print this page

        

@@ -45,45 +45,64 @@
 
     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) {
+            if (rem % alignment != 0)
+                throw new IllegalArgumentException("DirectByteBuffer is not properly aligned");
+            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;
         } finally {
             Util.offerFirstTemporaryDirectBuffer(bb);
         }
     }
 
-    private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb,
-                                             long position, NativeDispatcher nd)
+    private static int writeFromNativeBuffer(FileDescriptor fd, ByteBuffer bb, 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 && (bb.alignmentOffset(pos, alignment) != 0)  && (rem % alignment != 0)) {
+            throw new IllegalArgumentException("DirectByteBuffer is not properly aligned");
+        }
+
         int written = 0;
         if (rem == 0)
             return 0;
         if (position != -1) {
             written = nd.pwrite(fd,

@@ -98,17 +117,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 +146,23 @@
                 ByteBuffer buf = bufs[i];
                 int pos = buf.position();
                 int lim = buf.limit();
                 assert (pos <= lim);
                 int rem = (pos <= lim ? lim - pos : 0);
+                if (directIO && (rem % alignment != 0))
+                    throw new IllegalArgumentException("IO size or position is not aligned");
+
                 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 +217,54 @@
 
     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;
+        if (directIO) {
+            if (dst.remaining() % alignment != 0)
+                throw new IllegalArgumentException("DirectByteBuffer is not properly aligned");
+            bb = Util.getTemporaryAlignedDirectBuffer(dst.remaining(), alignment);
+        } else {
+            bb = Util.getTemporaryDirectBuffer(dst.remaining());   
+        }
         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)
+    private static int readIntoNativeBuffer(FileDescriptor fd, ByteBuffer bb, 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 && !(bb.alignmentOffset(pos, alignment) != 0) && (rem % alignment != 0))
+            throw new IllegalArgumentException("DirectByteBuffer is not properly aligned");
+
         if (rem == 0)
             return 0;
         int n = 0;
         if (position != -1) {
             n = nd.pread(fd, ((DirectBuffer)bb).address() + pos,

@@ -228,17 +278,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 +310,24 @@
                 int pos = buf.position();
                 int lim = buf.limit();
                 assert (pos <= lim);
                 int rem = (pos <= lim ? lim - pos : 0);
 
+                if (directIO && (rem % alignment != 0))
+                    throw new IllegalArgumentException("IO size or position is not aligned");
+                
                 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 >