< prev index next >
src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java
Print this page
@@ -47,10 +47,16 @@
import jdk.internal.misc.JavaNioAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.ref.Cleaner;
import sun.security.action.GetPropertyAction;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.FileSystemException;
+
public class FileChannelImpl
extends FileChannel
{
// Memory allocation size for mapping buffers
private static final long allocationGranularity;
@@ -83,28 +89,59 @@
private final Object positionLock = new Object();
// Positional-read is not interruptible
private volatile boolean uninterruptible;
+ //directIO
+ private volatile boolean direct;
+
+ //IO alignment for DirectIO
+ private volatile int alignment = -1;
+
private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
- boolean writable, Object parent)
+ boolean writable, boolean direct, Object parent)
{
this.fd = fd;
this.readable = readable;
this.writable = writable;
this.parent = parent;
this.path = path;
+ this.direct = direct;
+ if (direct)
+ setDirectIO();
this.nd = new FileDispatcherImpl();
}
+ private void setDirectIO()
+ {
+ if (alignment == -1) {
+ Path fp = Paths.get(path);
+ try {
+ setDirect0(fd);
+ FileStore fs = Files.getFileStore(fp);
+ this.alignment = fs.getBlockSize();
+ } catch (IOException e) {
+ this.alignment = -1;
+ throw new UnsupportedOperationException("Error setting up DirectIO");
+ }
+ }
+ }
+
// Used by FileInputStream.getChannel(), FileOutputStream.getChannel
// and RandomAccessFile.getChannel()
public static FileChannel open(FileDescriptor fd, String path,
boolean readable, boolean writable,
Object parent)
{
- return new FileChannelImpl(fd, path, readable, writable, parent);
+ return new FileChannelImpl(fd, path, readable, writable, false, parent);
+ }
+
+ public static FileChannel open(FileDescriptor fd, String path,
+ boolean readable, boolean writable,
+ boolean direct, Object parent)
+ {
+ return new FileChannelImpl(fd, path, readable, writable, direct, parent);
}
private void ensureOpen() throws IOException {
if (!isOpen())
throw new ClosedChannelException();
@@ -148,10 +185,13 @@
}
}
public int read(ByteBuffer dst) throws IOException {
+ if (direct && ((dst.remaining() % alignment != 0) ||
+ (position() % alignment != 0)))
+ throw new IllegalArgumentException("IO size or position is not aligned");
ensureOpen();
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
int n = 0;
@@ -160,11 +200,11 @@
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
- n = IOUtil.read(fd, dst, -1, nd);
+ n = IOUtil.read(fd, dst, -1, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
@@ -176,10 +216,14 @@
public long read(ByteBuffer[] dsts, int offset, int length)
throws IOException
{
if ((offset < 0) || (length < 0) || (offset > dsts.length - length))
throw new IndexOutOfBoundsException();
+
+ if (direct && (position() % alignment != 0))
+ throw new IllegalArgumentException("Position is not aligned");
+
ensureOpen();
if (!readable)
throw new NonReadableChannelException();
synchronized (positionLock) {
long n = 0;
@@ -188,11 +232,11 @@
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
- n = IOUtil.read(fd, dsts, offset, length, nd);
+ n = IOUtil.read(fd, dsts, offset, length, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
@@ -200,23 +244,27 @@
}
}
}
public int write(ByteBuffer src) throws IOException {
+
ensureOpen();
if (!writable)
throw new NonWritableChannelException();
+ if (direct && ((src.remaining() % alignment != 0) ||
+ (position() % alignment != 0)))
+ throw new IllegalArgumentException("IO size or position is not aligned");
synchronized (positionLock) {
int n = 0;
int ti = -1;
try {
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
- n = IOUtil.write(fd, src, -1, nd);
+ n = IOUtil.write(fd, src, -1, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
@@ -231,20 +279,24 @@
if ((offset < 0) || (length < 0) || (offset > srcs.length - length))
throw new IndexOutOfBoundsException();
ensureOpen();
if (!writable)
throw new NonWritableChannelException();
+
+ if (direct && (position() % alignment != 0))
+ throw new IllegalArgumentException("Position is not aligned");
+
synchronized (positionLock) {
long n = 0;
int ti = -1;
try {
begin();
ti = threads.add();
if (!isOpen())
return 0;
do {
- n = IOUtil.write(fd, srcs, offset, length, nd);
+ n = IOUtil.write(fd, srcs, offset, length, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
@@ -723,10 +775,14 @@
throw new NullPointerException();
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (!readable)
throw new NonReadableChannelException();
+ if (direct && ((dst.remaining() % alignment != 0) ||
+ (position % alignment != 0)))
+ throw new IllegalArgumentException("IO size or position is not aligned");
+
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
return readInternal(dst, position);
}
@@ -745,11 +801,11 @@
if (interruptible) begin();
ti = threads.add();
if (!isOpen())
return -1;
do {
- n = IOUtil.read(fd, dst, position, nd);
+ n = IOUtil.read(fd, dst, position, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
if (interruptible) end(n > 0);
@@ -762,10 +818,14 @@
throw new NullPointerException();
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (!writable)
throw new NonWritableChannelException();
+ if (direct && ((src.remaining() % alignment != 0) ||
+ (position % alignment != 0)))
+ throw new IllegalArgumentException("IO size or position is not aligned");
+
ensureOpen();
if (nd.needsPositionLock()) {
synchronized (positionLock) {
return writeInternal(src, position);
}
@@ -782,11 +842,11 @@
begin();
ti = threads.add();
if (!isOpen())
return -1;
do {
- n = IOUtil.write(fd, src, position, nd);
+ n = IOUtil.write(fd, src, position, direct, alignment, nd);
} while ((n == IOStatus.INTERRUPTED) && isOpen());
return IOStatus.normalize(n);
} finally {
threads.remove(ti);
end(n > 0);
@@ -1226,10 +1286,12 @@
private native long position0(FileDescriptor fd, long offset);
// Caches fieldIDs
private static native long initIDs();
+ private native int setDirect0(FileDescriptor fd) throws IOException;
+
static {
IOUtil.load();
allocationGranularity = initIDs();
}
< prev index next >