< 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 >