diff options
author | jfrijters <jfrijters> | 2013-08-15 16:47:21 +0400 |
---|---|---|
committer | jfrijters <jfrijters> | 2013-08-15 16:47:21 +0400 |
commit | 898e1dedc210a812829c5914249389c7d159bfb3 (patch) | |
tree | f076c216e2e1f2db454586c49c328cea3051b8d4 | |
parent | 76f3faadd8acb83d089992efb44ce4e5b9458124 (diff) |
Merged IoTrace hooks.
-rw-r--r-- | openjdk/FORKED | 3 | ||||
-rw-r--r-- | openjdk/allsources.lst | 1 | ||||
-rw-r--r-- | openjdk/java/io/FileInputStream.java | 45 | ||||
-rw-r--r-- | openjdk/java/io/FileOutputStream.java | 45 | ||||
-rw-r--r-- | openjdk/java/io/RandomAccessFile.java | 59 | ||||
-rw-r--r-- | openjdk/sun/misc/IoTrace.java | 170 | ||||
-rw-r--r-- | openjdk/sun/nio/ch/FileChannelImpl.java | 29 | ||||
-rw-r--r-- | openjdk/sun/nio/fs/NetFileSystemProvider.java | 2 |
8 files changed, 320 insertions, 34 deletions
diff --git a/openjdk/FORKED b/openjdk/FORKED index 22bce710..64e8faf2 100644 --- a/openjdk/FORKED +++ b/openjdk/FORKED @@ -82,7 +82,8 @@ jdk/src/share/classes/sun/font/StrikeCache.java=sun/font/StrikeCache.java jdk/src/share/classes/sun/management/GcInfoBuilder.java=sun/management/GcInfoBuilder.java jdk/src/share/classes/sun/management/ManagementFactoryHelper.java=sun/management/ManagementFactoryHelper.java jdk/src/share/classes/sun/management/VMManagementImpl.java=sun/management/VMManagementImpl.java -jdk/src/share/classes/sun/misc/JavaAWTAccess=sun/misc/JavaAWTAccess +jdk/src/share/classes/sun/misc/IoTrace.java=sun/misc/IoTrace.java +jdk/src/share/classes/sun/misc/JavaAWTAccess.java=sun/misc/JavaAWTAccess.java jdk/src/share/classes/sun/misc/SharedSecrets.java=sun/misc/SharedSecrets.java jdk/src/share/classes/sun/misc/VM.java=sun/misc/VM.java jdk/src/share/classes/sun/net/sdp/SdpSupport.java=sun/net/sdp/SdpSupport.java diff --git a/openjdk/allsources.lst b/openjdk/allsources.lst index 34d5c2b8..533d7645 100644 --- a/openjdk/allsources.lst +++ b/openjdk/allsources.lst @@ -204,6 +204,7 @@ sun/management/GcInfoBuilder.java sun/management/ManagementFactoryHelper.java sun/management/VMManagementImpl.java sun/misc/FileURLMapper.java +sun/misc/IoTrace.java sun/misc/JavaAWTAccess.java sun/misc/MiscHelper.java sun/misc/OSEnvironment.java diff --git a/openjdk/java/io/FileInputStream.java b/openjdk/java/io/FileInputStream.java index a0bc2247..3547947f 100644 --- a/openjdk/java/io/FileInputStream.java +++ b/openjdk/java/io/FileInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -51,6 +52,9 @@ class FileInputStream extends InputStream /* File Descriptor - handle to the open file */ private final FileDescriptor fd; + /* The path of the referenced file (null if the stream is created with a file descriptor) */ + private final String path; + private FileChannel channel = null; private final Object closeLock = new Object(); @@ -133,8 +137,14 @@ class FileInputStream extends InputStream if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ fd = new FileDescriptor(); fd.incrementAndGetUseCount(); + this.path = name; open(name); } @@ -171,6 +181,7 @@ class FileInputStream extends InputStream security.checkRead(fdObj); } fd = fdObj; + path = null; /* * FileDescriptor is being shared by streams. @@ -197,9 +208,15 @@ class FileInputStream extends InputStream * file is reached. * @exception IOException if an I/O error occurs. */ - public int read() throws IOException - { - return fd.read(); + public int read() throws IOException { + Object traceContext = IoTrace.fileReadBegin(path); + int b = 0; + try { + b = fd.read(); + } finally { + IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1); + } + return b; } /** @@ -226,7 +243,14 @@ class FileInputStream extends InputStream * @exception IOException if an I/O error occurs. */ public int read(byte b[]) throws IOException { - return readBytes(b, 0, b.length); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = readBytes(b, 0, b.length); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -248,7 +272,14 @@ class FileInputStream extends InputStream * @exception IOException if an I/O error occurs. */ public int read(byte b[], int off, int len) throws IOException { - return readBytes(b, off, len); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = readBytes(b, off, len); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -376,7 +407,7 @@ class FileInputStream extends InputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, true, false, this); + channel = FileChannelImpl.open(fd, path, true, false, this); /* * Increment fd's use count. Invoking the channel's close() diff --git a/openjdk/java/io/FileOutputStream.java b/openjdk/java/io/FileOutputStream.java index e931fe68..dae9d4bc 100644 --- a/openjdk/java/io/FileOutputStream.java +++ b/openjdk/java/io/FileOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -58,6 +59,11 @@ class FileOutputStream extends OutputStream private final FileDescriptor fd; /** + * The path of the referenced file (null if the stream is created with a file descriptor) + */ + private final String path; + + /** * True if the file is opened for append. */ private final boolean append; @@ -205,9 +211,14 @@ class FileOutputStream extends OutputStream if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ this.fd = new FileDescriptor(); this.append = append; - + this.path = name; fd.incrementAndGetUseCount(); open(name, append); } @@ -244,6 +255,7 @@ class FileOutputStream extends OutputStream security.checkWrite(fdObj); } this.fd = fdObj; + this.path = null; this.append = false; /* @@ -287,7 +299,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(int b) throws IOException { - write(b, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + write(b, append); + bytesWritten = 1; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -312,7 +331,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[]) throws IOException { - writeBytes(b, 0, b.length, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + writeBytes(b, 0, b.length, append); + bytesWritten = b.length; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -325,7 +351,14 @@ class FileOutputStream extends OutputStream * @exception IOException if an I/O error occurs. */ public void write(byte b[], int off, int len) throws IOException { - writeBytes(b, off, len, append); + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + writeBytes(b, off, len, append); + bytesWritten = len; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -408,7 +441,7 @@ class FileOutputStream extends OutputStream public FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, false, true, append, this); + channel = FileChannelImpl.open(fd, path, false, true, append, this); /* * Increment fd's use count. Invoking the channel's close() diff --git a/openjdk/java/io/RandomAccessFile.java b/openjdk/java/io/RandomAccessFile.java index 3cddafd2..61fc27a7 100644 --- a/openjdk/java/io/RandomAccessFile.java +++ b/openjdk/java/io/RandomAccessFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, 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 @@ -27,6 +27,7 @@ package java.io; import java.nio.channels.FileChannel; import sun.nio.ch.FileChannelImpl; +import sun.misc.IoTrace; /** @@ -62,6 +63,9 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { private FileChannel channel = null; private boolean rw; + /* The path of the referenced file */ + private final String path; + private Object closeLock = new Object(); private volatile boolean closed = false; @@ -228,8 +232,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { if (name == null) { throw new NullPointerException(); } + /* + if (file.isInvalid()) { + throw new FileNotFoundException("Invalid file path"); + } + */ fd = new FileDescriptor(); fd.incrementAndGetUseCount(); + this.path = name; open(name, imode); } @@ -267,7 +277,7 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { public final FileChannel getChannel() { synchronized (this) { if (channel == null) { - channel = FileChannelImpl.open(fd, true, rw, this); + channel = FileChannelImpl.open(fd, path, true, rw, this); /* * FileDescriptor could be shared by FileInputStream or @@ -325,9 +335,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @exception IOException if an I/O error occurs. Not thrown if * end-of-file has been reached. */ - public int read() throws IOException - { - return fd.read(); + public int read() throws IOException { + Object traceContext = IoTrace.fileReadBegin(path); + int b = 0; + try { + b = fd.read(); + } finally { + IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1); + } + return b; } /** @@ -339,7 +355,14 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { */ private int readBytes(byte b[], int off, int len) throws IOException { - return fd.readBytes(b, off, len); + Object traceContext = IoTrace.fileReadBegin(path); + int bytesRead = 0; + try { + bytesRead = fd.readBytes(b, off, len); + } finally { + IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead); + } + return bytesRead; } /** @@ -479,9 +502,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @param b the <code>byte</code> to be written. * @exception IOException if an I/O error occurs. */ - public void write(int b) throws IOException - { - fd.write(b); + public void write(int b) throws IOException { + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + fd.write(b); + bytesWritten = 1; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** @@ -492,9 +521,15 @@ public class RandomAccessFile implements DataOutput, DataInput, Closeable { * @param len the number of bytes that are written * @exception IOException If an I/O error has occurred. */ - private void writeBytes(byte b[], int off, int len) throws IOException - { - fd.writeBytes(b, off, len); + private void writeBytes(byte b[], int off, int len) throws IOException { + Object traceContext = IoTrace.fileWriteBegin(path); + int bytesWritten = 0; + try { + fd.writeBytes(b, off, len); + bytesWritten = len; + } finally { + IoTrace.fileWriteEnd(traceContext, bytesWritten); + } } /** diff --git a/openjdk/sun/misc/IoTrace.java b/openjdk/sun/misc/IoTrace.java new file mode 100644 index 00000000..ab15ed16 --- /dev/null +++ b/openjdk/sun/misc/IoTrace.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2012, 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.misc; + +import java.net.InetAddress; + +/** + * Utility class used to identify trace points for I/O calls. + * <p> + * To use this class, a diagnostic tool must redefine this class with a version + * that contains calls to the the diagnostic tool. This implementation will then + * receive callbacks when file and socket operations are performed. The reason + * for requiring a redefine of the class is to avoid any overhead caused by the + * instrumentation. + * <p> + * The xxBegin() methods return a "context". This can be any Object. This + * context will be passed to the corresponding xxEnd() method. This way, an + * implementation can correlate the beginning of an operation with the end. + * <p> + * It is possible for a xxEnd() method to be called with a null handle. This + * happens if tracing was started between the call to xxBegin() and xxEnd(), in + * which case xxBegin() would not have been called. It is the implementation's + * responsibility to not throw an exception in this case. + * <p> + * Only blocking I/O operations are identified with this facility. + * <p> + * <b>Warning</b> + * <p> + * These methods are called from sensitive points in the I/O subsystem. Great + * care must be taken to not interfere with ongoing operations or cause + * deadlocks. In particular: + * <ul> + * <li>Implementations must not throw exceptions since this will cause + * disruptions to the I/O operations. + * <li>Implementations must not do I/O operations since this will lead to an + * endless loop. + * <li>Since the hooks may be called while holding low-level locks in the I/O + * subsystem, implementations must be careful with synchronization or + * interaction with other threads to avoid deadlocks in the VM. + * </ul> + */ +public final class IoTrace { + private IoTrace() { + } + + /** + * Called before data is read from a socket. + * + * @return a context object + */ + public static Object socketReadBegin() { + return null; + } + + /** + * Called after data is read from the socket. + * + * @param context + * the context returned by the previous call to socketReadBegin() + * @param address + * the remote address the socket is bound to + * @param port + * the remote port the socket is bound to + * @param timeout + * the SO_TIMEOUT value of the socket (in milliseconds) or 0 if + * there is no timeout set + * @param bytesRead + * the number of bytes read from the socket, 0 if there was an + * error reading from the socket + */ + public static void socketReadEnd(Object context, InetAddress address, int port, + int timeout, long bytesRead) { + } + + /** + * Called before data is written to a socket. + * + * @return a context object + */ + public static Object socketWriteBegin() { + return null; + } + + /** + * Called after data is written to a socket. + * + * @param context + * the context returned by the previous call to + * socketWriteBegin() + * @param address + * the remote address the socket is bound to + * @param port + * the remote port the socket is bound to + * @param bytesWritten + * the number of bytes written to the socket, 0 if there was an + * error writing to the socket + */ + public static void socketWriteEnd(Object context, InetAddress address, int port, + long bytesWritten) { + } + + /** + * Called before data is read from a file. + * + * @param path + * the path of the file + * @return a context object + */ + public static Object fileReadBegin(String path) { + return null; + } + + /** + * Called after data is read from a file. + * + * @param context + * the context returned by the previous call to fileReadBegin() + * @param bytesRead + * the number of bytes written to the file, 0 if there was an + * error writing to the file + */ + public static void fileReadEnd(Object context, long bytesRead) { + } + + /** + * Called before data is written to a file. + * + * @param path + * the path of the file + * @return a context object + */ + public static Object fileWriteBegin(String path) { + return null; + } + + /** + * Called after data is written to a file. + * + * @param context + * the context returned by the previous call to fileReadBegin() + * @param bytesWritten + * the number of bytes written to the file, 0 if there was an + * error writing to the file + */ + public static void fileWriteEnd(Object context, long bytesWritten) { + } +} diff --git a/openjdk/sun/nio/ch/FileChannelImpl.java b/openjdk/sun/nio/ch/FileChannelImpl.java index 160e1f54..902509bd 100644 --- a/openjdk/sun/nio/ch/FileChannelImpl.java +++ b/openjdk/sun/nio/ch/FileChannelImpl.java @@ -29,8 +29,6 @@ import cli.Microsoft.Win32.SafeHandles.SafeFileHandle; import cli.System.IntPtr; import cli.System.IO.FileStream; import cli.System.Runtime.InteropServices.DllImportAttribute; -import cli.System.Runtime.InteropServices.StructLayoutAttribute; -import cli.System.Runtime.InteropServices.LayoutKind; import java.io.FileDescriptor; import java.io.IOException; import java.nio.ByteBuffer; @@ -40,6 +38,7 @@ import java.util.ArrayList; import java.util.List; import java.security.AccessController; import sun.misc.Cleaner; +import sun.misc.IoTrace; import sun.security.action.GetPropertyAction; public class FileChannelImpl @@ -64,13 +63,16 @@ public class FileChannelImpl // Required to prevent finalization of creating stream (immutable) private final Object parent; + // The path of the referenced file (null if the parent stream is created with a file descriptor) + private final String path; + // Thread-safe set of IDs of native threads, for signalling private final NativeThreadSet threads = new NativeThreadSet(2); // Lock for operations involving position and size private final Object positionLock = new Object(); - private FileChannelImpl(FileDescriptor fd, boolean readable, + private FileChannelImpl(FileDescriptor fd, String path, boolean readable, boolean writable, boolean append, Object parent) { this.fd = fd; @@ -78,23 +80,24 @@ public class FileChannelImpl this.writable = writable; this.append = append; this.parent = parent; + this.path = path; this.nd = new FileDispatcherImpl(append); } // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel() - public static FileChannel open(FileDescriptor fd, + public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, Object parent) { - return new FileChannelImpl(fd, readable, writable, false, parent); + return new FileChannelImpl(fd, path, readable, writable, false, parent); } // Used by FileOutputStream.getChannel - public static FileChannel open(FileDescriptor fd, + public static FileChannel open(FileDescriptor fd, String path, boolean readable, boolean writable, boolean append, Object parent) { - return new FileChannelImpl(fd, readable, writable, append, parent); + return new FileChannelImpl(fd, path, readable, writable, append, parent); } private void ensureOpen() throws IOException { @@ -142,6 +145,7 @@ public class FileChannelImpl synchronized (positionLock) { int n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -153,6 +157,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -170,6 +175,7 @@ public class FileChannelImpl synchronized (positionLock) { long n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -181,6 +187,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -194,6 +201,7 @@ public class FileChannelImpl synchronized (positionLock) { int n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -206,6 +214,7 @@ public class FileChannelImpl } finally { threads.remove(ti); end(n > 0); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); assert IOStatus.check(n); } } @@ -222,6 +231,7 @@ public class FileChannelImpl synchronized (positionLock) { long n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -233,6 +243,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -513,6 +524,7 @@ public class FileChannelImpl ensureOpen(); int n = 0; int ti = -1; + Object traceContext = IoTrace.fileReadBegin(path); try { begin(); ti = threads.add(); @@ -524,6 +536,7 @@ public class FileChannelImpl return IOStatus.normalize(n); } finally { threads.remove(ti); + IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0); end(n > 0); assert IOStatus.check(n); } @@ -539,6 +552,7 @@ public class FileChannelImpl ensureOpen(); int n = 0; int ti = -1; + Object traceContext = IoTrace.fileWriteBegin(path); try { begin(); ti = threads.add(); @@ -551,6 +565,7 @@ public class FileChannelImpl } finally { threads.remove(ti); end(n > 0); + IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0); assert IOStatus.check(n); } } diff --git a/openjdk/sun/nio/fs/NetFileSystemProvider.java b/openjdk/sun/nio/fs/NetFileSystemProvider.java index e7b7e140..3c569b1e 100644 --- a/openjdk/sun/nio/fs/NetFileSystemProvider.java +++ b/openjdk/sun/nio/fs/NetFileSystemProvider.java @@ -338,7 +338,7 @@ final class NetFileSystemProvider extends AbstractFileSystemProvider } } - return FileChannelImpl.open(open(npath.path, mode, rights, share, options), read, write, append, null); + return FileChannelImpl.open(open(npath.path, mode, rights, share, options), npath.path, read, write, append, null); } private static FileDescriptor open(String path, int mode, int rights, int share, int options) throws IOException |