mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8293331: Refactor FileDispatcherImpl into operating system-specific components
Reviewed-by: alanb
This commit is contained in:
parent
f751e6087d
commit
48cc15602b
14 changed files with 959 additions and 704 deletions
|
@ -64,18 +64,12 @@ import jdk.internal.access.foreign.UnmapperProxy;
|
|||
public class FileChannelImpl
|
||||
extends FileChannel
|
||||
{
|
||||
// Memory allocation size for mapping buffers
|
||||
private static final long allocationGranularity;
|
||||
|
||||
// Access to FileDescriptor internals
|
||||
private static final JavaIOFileDescriptorAccess fdAccess =
|
||||
SharedSecrets.getJavaIOFileDescriptorAccess();
|
||||
|
||||
// Maximum direct transfer size
|
||||
private static final int MAX_DIRECT_TRANSFER_SIZE;
|
||||
|
||||
// Used to make native read and write calls
|
||||
private final FileDispatcher nd;
|
||||
private static final FileDispatcher nd = new FileDispatcherImpl();
|
||||
|
||||
// File descriptor
|
||||
private final FileDescriptor fd;
|
||||
|
@ -130,12 +124,11 @@ public class FileChannelImpl
|
|||
boolean writable, boolean direct, Object parent)
|
||||
{
|
||||
this.fd = fd;
|
||||
this.path = path;
|
||||
this.readable = readable;
|
||||
this.writable = writable;
|
||||
this.parent = parent;
|
||||
this.path = path;
|
||||
this.direct = direct;
|
||||
this.nd = new FileDispatcherImpl();
|
||||
this.parent = parent;
|
||||
if (direct) {
|
||||
assert path != null;
|
||||
this.alignment = nd.setDirectIO(fd, path);
|
||||
|
@ -151,8 +144,9 @@ public class FileChannelImpl
|
|||
CleanerFactory.cleaner().register(this, new Closer(fd));
|
||||
}
|
||||
|
||||
// Used by FileInputStream.getChannel(), FileOutputStream.getChannel
|
||||
// and RandomAccessFile.getChannel()
|
||||
|
||||
// Used by FileInputStream::getChannel, FileOutputStream::getChannel,
|
||||
// and RandomAccessFile::getChannel
|
||||
public static FileChannel open(FileDescriptor fd, String path,
|
||||
boolean readable, boolean writable,
|
||||
boolean direct, Object parent)
|
||||
|
@ -574,7 +568,7 @@ public class FileChannelImpl
|
|||
do {
|
||||
long comp = Blocker.begin();
|
||||
try {
|
||||
n = transferTo0(fd, position, icount, targetFD, append);
|
||||
n = nd.transferTo(fd, position, icount, targetFD, append);
|
||||
} finally {
|
||||
Blocker.end(comp);
|
||||
}
|
||||
|
@ -779,7 +773,7 @@ public class FileChannelImpl
|
|||
if (sz > 0) {
|
||||
// Attempt a direct transfer, if the kernel supports it, limiting
|
||||
// the number of bytes according to which platform
|
||||
int icount = (int)Math.min(count, MAX_DIRECT_TRANSFER_SIZE);
|
||||
int icount = (int)Math.min(count, nd.maxDirectTransferSize());
|
||||
long n;
|
||||
if ((n = transferToDirectly(position, icount, target)) >= 0)
|
||||
return n;
|
||||
|
@ -813,7 +807,7 @@ public class FileChannelImpl
|
|||
long comp = Blocker.begin();
|
||||
try {
|
||||
boolean append = fdAccess.getAppend(fd);
|
||||
n = transferFrom0(srcFD, fd, position, count, append);
|
||||
n = nd.transferFrom(srcFD, fd, position, count, append);
|
||||
} finally {
|
||||
Blocker.end(comp);
|
||||
}
|
||||
|
@ -1052,9 +1046,6 @@ public class FileChannelImpl
|
|||
private abstract static class Unmapper
|
||||
implements Runnable, UnmapperProxy
|
||||
{
|
||||
// may be required to close file
|
||||
private static final NativeDispatcher nd = new FileDispatcherImpl();
|
||||
|
||||
private volatile long address;
|
||||
protected final long size;
|
||||
protected final long cap;
|
||||
|
@ -1094,7 +1085,7 @@ public class FileChannelImpl
|
|||
public void unmap() {
|
||||
if (address == 0)
|
||||
return;
|
||||
unmap0(address, size);
|
||||
nd.unmap(address, size);
|
||||
address = 0;
|
||||
|
||||
// if this mapping has a valid file descriptor then we close it
|
||||
|
@ -1313,12 +1304,12 @@ public class FileChannelImpl
|
|||
return null;
|
||||
}
|
||||
|
||||
pagePosition = (int)(position % allocationGranularity);
|
||||
pagePosition = (int)(position % nd.allocationGranularity());
|
||||
long mapPosition = position - pagePosition;
|
||||
mapSize = size + pagePosition;
|
||||
try {
|
||||
// If map0 did not throw an exception, the address is valid
|
||||
addr = map0(fd, prot, mapPosition, mapSize, isSync);
|
||||
// If map did not throw an exception, the address is valid
|
||||
addr = nd.map(fd, prot, mapPosition, mapSize, isSync);
|
||||
} catch (OutOfMemoryError x) {
|
||||
// An OutOfMemoryError may indicate that we've exhausted
|
||||
// memory so force gc and re-attempt map
|
||||
|
@ -1329,7 +1320,7 @@ public class FileChannelImpl
|
|||
Thread.currentThread().interrupt();
|
||||
}
|
||||
try {
|
||||
addr = map0(fd, prot, mapPosition, mapSize, isSync);
|
||||
addr = nd.map(fd, prot, mapPosition, mapSize, isSync);
|
||||
} catch (OutOfMemoryError y) {
|
||||
// After a second OOME, fail
|
||||
throw new IOException("Map failed", y);
|
||||
|
@ -1343,15 +1334,15 @@ public class FileChannelImpl
|
|||
try {
|
||||
mfd = nd.duplicateForMapping(fd);
|
||||
} catch (IOException ioe) {
|
||||
unmap0(addr, mapSize);
|
||||
nd.unmap(addr, mapSize);
|
||||
throw ioe;
|
||||
}
|
||||
|
||||
assert (IOStatus.checkAll(addr));
|
||||
assert (addr % allocationGranularity == 0);
|
||||
assert (addr % nd.allocationGranularity() == 0);
|
||||
Unmapper um = (isSync
|
||||
? new SyncUnmapper(addr, mapSize, size, mfd, pagePosition)
|
||||
: new DefaultUnmapper(addr, mapSize, size, mfd, pagePosition));
|
||||
? new SyncUnmapper(addr, mapSize, size, mfd, pagePosition)
|
||||
: new DefaultUnmapper(addr, mapSize, size, mfd, pagePosition));
|
||||
return um;
|
||||
} finally {
|
||||
threads.remove(ti);
|
||||
|
@ -1575,37 +1566,4 @@ public class FileChannelImpl
|
|||
assert fileLockTable != null;
|
||||
fileLockTable.remove(fli);
|
||||
}
|
||||
|
||||
// -- Native methods --
|
||||
|
||||
// Creates a new mapping
|
||||
private native long map0(FileDescriptor fd, int prot, long position,
|
||||
long length, boolean isSync)
|
||||
throws IOException;
|
||||
|
||||
// Removes an existing mapping
|
||||
private static native int unmap0(long address, long length);
|
||||
|
||||
// Transfers from src to dst, or returns IOStatus.UNSUPPORTED (-4) or
|
||||
// IOStatus.UNSUPPORTED_CASE (-6) if the kernel does not support it
|
||||
private static native long transferTo0(FileDescriptor src, long position,
|
||||
long count, FileDescriptor dst,
|
||||
boolean append);
|
||||
|
||||
private static native long transferFrom0(FileDescriptor src,
|
||||
FileDescriptor dst,
|
||||
long position, long count,
|
||||
boolean append);
|
||||
|
||||
// Retrieves the maximum size of a transfer
|
||||
private static native int maxDirectTransferSize0();
|
||||
|
||||
// Retrieves allocation granularity
|
||||
private static native long allocationGranularity0();
|
||||
|
||||
static {
|
||||
IOUtil.load();
|
||||
allocationGranularity = allocationGranularity0();
|
||||
MAX_DIRECT_TRANSFER_SIZE = maxDirectTransferSize0();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue