changeset 5201:09145b546a2b jdk7u6-b20

Merge
author lana
date Wed, 11 Jul 2012 20:30:23 -0700
parents 22a3627aafa0 0039f5c7fb51
children 243717d7fe95
files test/java/io/FileDescriptor/Sharing.java
diffstat 14 files changed, 402 insertions(+), 646 deletions(-) [+]
line wrap: on
line diff
--- a/src/linux/doc/man/jcmd.1	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/linux/doc/man/jcmd.1	Wed Jul 11 20:30:23 2012 -0700
@@ -19,7 +19,7 @@
 ." or visit www.oracle.com if you need additional information or have any
 ." questions.
 ."
-.TH jcmd 1 "16 Mar 2012"
+.TH jcmd 1 "10 Jul 2012"
 
 .LP
 .SH "Name"
@@ -56,7 +56,7 @@
 When a process id is specified on the command line, jcmd sends the diagnostic command request to the process with this id.
 .LP
 .LP
-When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes with this main class.
+When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes for which the command line argument is a substring of the Java process' main class.
 .LP
 .LP
 With the PerfCounter.print argument, jcmd prints the performance counters available on the targeted Java process(es).
@@ -73,11 +73,9 @@
 .TP 3
 \-l 
 Prints the list of running Java processes with their process id, their main class and their command line arguments. 
-.br
 .TP 3
 \-h 
 Prints a help message. 
-.br
 .TP 3
 \-help 
 Prints a help message. 
@@ -90,19 +88,15 @@
 .TP 3
 pid 
 Identifies the process that receives the diagnostic command requests. The process must be a Java process. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
-.br
 .TP 3
 main class 
-Main class of the process that receives the diagnostic command requests. If several running Java processes share this main class, the diagnostic command request is sent to all these processes. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
-.br
+Main class of the process that receives the diagnostic command requests. When matching processes, any process whose main class name contains the specified string as a substring will be matched. If several running Java processes share this main class, the diagnostic command request is sent to all these processes. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
 .TP 3
 command [arguments] 
-Invoke the diagnostic command called \f2command\fP on the targeted Java process(es). The list of available diagnostic commands for a given process can be obtained by invoking the \f3help\fP command on this process. Each diagnostic command has its own set of \f2arguments\fP, which can be obtained by invoking the \f3help\fP command followed by the command name. 
-.br
+Invoke the diagnostic command called \f2command\fP on the targeted Java process(es). The list of available diagnostic commands for a given process can be obtained by invoking the \f3help\fP command on this process. Each diagnostic command has its own set of \f2arguments\fP, which can be obtained by invoking the the command name followed by \f3help\fP. 
 .TP 3
-Counter.print 
+PerfCounter.print 
 Print the performance counters available on the targeted Java process(es). The list of performance counters may vary with the Java process. 
-.br
 .TP 3
 \-f file 
 Read commands from \f2file\fP and invoke them on the targeted Java process(es). In \f2file\fP, each command must be written on a single line. Lines starting with # are ignored. Processing of \f2file\fP ends when all lines have been invoked or when a line containing the \f3stop\fP keyword is read. 
--- a/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CDropTargetContextPeer.java	Wed Jul 11 20:30:23 2012 -0700
@@ -128,6 +128,15 @@
         }
     }
 
+    @Override
+    protected int postDropTargetEvent(Component component, int x, int y, int dropAction,
+                                      int actions, long[] formats, long nativeCtxt, int eventID,
+                                      boolean dispatchType) {
+        // On MacOS X all the DnD events should be synchronous
+        return super.postDropTargetEvent(component, x, y, dropAction, actions, formats, nativeCtxt,
+                eventID, SunDropTargetContextPeer.DISPATCH_SYNC);
+    }
+
     // Signal drop complete:
     protected void doDropDone(boolean success, int dropAction, boolean isLocal) {
         long nativeDropTarget = this.getNativeDragContext();
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Wed Jul 11 20:30:23 2012 -0700
@@ -209,6 +209,7 @@
     private boolean undecorated; // initialized in getInitialStyleBits()
     private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
     private CPlatformResponder responder;
+    private volatile boolean zoomed = false; // from native perspective
 
     public CPlatformWindow(final PeerType peerType) {
         super(0, true);
@@ -471,26 +472,42 @@
         return this.visible;
     }
 
-    private void zoom() {
+    private boolean isMaximized() {
+        return undecorated ? this.normalBounds != null : zoomed;
+    }
+
+    private void maximize() {
+        if (isMaximized()) {
+            return;
+        }
         if (!undecorated) {
+            zoomed = true;
             CWrapper.NSWindow.zoom(getNSWindowPtr());
         } else {
-            // OS X handles -zoom incorrectly for undecorated windows
-            final boolean isZoomed = this.normalBounds == null;
-            deliverZoom(isZoomed);
+            deliverZoom(true);
 
-            Rectangle toBounds;
-            if (isZoomed) {
-                this.normalBounds = peer.getBounds();
-                long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
-                toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
-                // Flip the y coordinate
-                Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
-                toBounds.y = frame.height - toBounds.y - toBounds.height;
-            } else {
-                toBounds = normalBounds;
-                this.normalBounds = null;
-            }
+            this.normalBounds = peer.getBounds();
+            long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
+            Rectangle toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
+            // Flip the y coordinate
+            Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
+            toBounds.y = frame.height - toBounds.y - toBounds.height;
+            setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
+        }
+    }
+
+    private void unmaximize() {
+        if (!isMaximized()) {
+            return;
+        }
+        if (!undecorated) {
+            zoomed = false;
+            CWrapper.NSWindow.zoom(getNSWindowPtr());
+        } else {
+            deliverZoom(false);
+
+            Rectangle toBounds = this.normalBounds;
+            this.normalBounds = null;
             setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
         }
     }
@@ -499,9 +516,9 @@
     public void setVisible(boolean visible) {
         final long nsWindowPtr = getNSWindowPtr();
 
-        // 1. Process parent-child relationship when hiding
+        // Process parent-child relationship when hiding
         if (!visible) {
-            // 1a. Unparent my children
+            // Unparent my children
             for (Window w : target.getOwnedWindows()) {
                 WindowPeer p = (WindowPeer)w.getPeer();
                 if (p instanceof LWWindowPeer) {
@@ -512,30 +529,17 @@
                 }
             }
 
-            // 1b. Unparent myself
+            // Unparent myself
             if (owner != null && owner.isVisible()) {
                 CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
             }
         }
 
-        // 2. Configure stuff
+        // Configure stuff
         updateIconImages();
         updateFocusabilityForAutoRequestFocus(false);
 
-        // 3. Manage the extended state when hiding
-        if (!visible) {
-            // Cancel out the current native state of the window
-            switch (peer.getState()) {
-                case Frame.ICONIFIED:
-                    CWrapper.NSWindow.deminiaturize(nsWindowPtr);
-                    break;
-                case Frame.MAXIMIZED_BOTH:
-                    zoom();
-                    break;
-            }
-        }
-
-        // 4. Actually show or hide the window
+        // Actually show or hide the window
         LWWindowPeer blocker = peer.getBlocker();
         if (blocker == null || !visible) {
             // If it ain't blocked, or is being hidden, go regular way
@@ -564,16 +568,19 @@
         }
         this.visible = visible;
 
-        // 5. Manage the extended state when showing
+        // Manage the extended state when showing
         if (visible) {
-            // Re-apply the extended state as expected in shared code
+            // Apply the extended state as expected in shared code
             if (target instanceof Frame) {
                 switch (((Frame)target).getExtendedState()) {
                     case Frame.ICONIFIED:
                         CWrapper.NSWindow.miniaturize(nsWindowPtr);
                         break;
                     case Frame.MAXIMIZED_BOTH:
-                        zoom();
+                        maximize();
+                        break;
+                    default: // NORMAL
+                        unmaximize(); // in case it was maximized, otherwise this is a no-op
                         break;
                 }
             }
@@ -581,12 +588,12 @@
 
         nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
 
-        // 6. Configure stuff #2
+        // Configure stuff #2
         updateFocusabilityForAutoRequestFocus(true);
 
-        // 7. Manage parent-child relationship when showing
+        // Manage parent-child relationship when showing
         if (visible) {
-            // 7a. Add myself as a child
+            // Add myself as a child
             if (owner != null && owner.isVisible()) {
                 CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
                 if (target.isAlwaysOnTop()) {
@@ -594,7 +601,7 @@
                 }
             }
 
-            // 7b. Add my own children to myself
+            // Add my own children to myself
             for (Window w : target.getOwnedWindows()) {
                 WindowPeer p = (WindowPeer)w.getPeer();
                 if (p instanceof LWWindowPeer) {
@@ -609,7 +616,7 @@
             }
         }
 
-        // 8. Deal with the blocker of the window being shown
+        // Deal with the blocker of the window being shown
         if (blocker != null && visible) {
             // Make sure the blocker is above its siblings
             ((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
@@ -767,7 +774,7 @@
                 if (prevWindowState == Frame.MAXIMIZED_BOTH) {
                     // let's return into the normal states first
                     // the zoom call toggles between the normal and the max states
-                    zoom();
+                    unmaximize();
                 }
                 CWrapper.NSWindow.miniaturize(nsWindowPtr);
                 break;
@@ -776,14 +783,14 @@
                     // let's return into the normal states first
                     CWrapper.NSWindow.deminiaturize(nsWindowPtr);
                 }
-                zoom();
+                maximize();
                 break;
             case Frame.NORMAL:
                 if (prevWindowState == Frame.ICONIFIED) {
                     CWrapper.NSWindow.deminiaturize(nsWindowPtr);
                 } else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
                     // the zoom call toggles between the normal and the max states
-                    zoom();
+                    unmaximize();
                 }
                 break;
             default:
--- a/src/share/classes/java/io/FileInputStream.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/share/classes/java/io/FileInputStream.java	Wed Jul 11 20:30:23 2012 -0700
@@ -56,6 +56,16 @@
     private final Object closeLock = new Object();
     private volatile boolean closed = false;
 
+    private static final ThreadLocal<Boolean> runningFinalize =
+        new ThreadLocal<>();
+
+    private static boolean isRunningFinalize() {
+        Boolean val;
+        if ((val = runningFinalize.get()) != null)
+            return val.booleanValue();
+        return false;
+    }
+
     /**
      * Creates a <code>FileInputStream</code> by
      * opening a connection to an actual file,
@@ -124,7 +134,7 @@
             throw new NullPointerException();
         }
         fd = new FileDescriptor();
-        fd.attach(this);
+        fd.incrementAndGetUseCount();
         open(name);
     }
 
@@ -164,9 +174,10 @@
 
         /*
          * FileDescriptor is being shared by streams.
-         * Register this stream with FileDescriptor tracker.
+         * Ensure that it's GC'ed only when all the streams/channels are done
+         * using it.
          */
-        fd.attach(this);
+        fd.incrementAndGetUseCount();
     }
 
     /**
@@ -293,13 +304,27 @@
             closed = true;
         }
         if (channel != null) {
+            /*
+             * Decrement the FD use count associated with the channel
+             * The use count is incremented whenever a new channel
+             * is obtained from this stream.
+             */
+           fd.decrementAndGetUseCount();
            channel.close();
         }
-        fd.closeAll(new Closeable() {
-            public void close() throws IOException {
-               close0();
-           }
-        });
+
+        /*
+         * Decrement the FD use count associated with this stream
+         */
+        int useCount = fd.decrementAndGetUseCount();
+
+        /*
+         * If FileDescriptor is still in use by another stream, the finalizer
+         * will not close it.
+         */
+        if ((useCount <= 0) || !isRunningFinalize()) {
+            close0();
+        }
     }
 
     /**
@@ -313,9 +338,7 @@
      * @see        java.io.FileDescriptor
      */
     public final FileDescriptor getFD() throws IOException {
-        if (fd != null) {
-            return fd;
-        }
+        if (fd != null) return fd;
         throw new IOException();
     }
 
@@ -339,6 +362,13 @@
         synchronized (this) {
             if (channel == null) {
                 channel = FileChannelImpl.open(fd, true, false, this);
+
+                /*
+                 * Increment fd's use count. Invoking the channel's close()
+                 * method will result in decrementing the use count set for
+                 * the channel.
+                 */
+                fd.incrementAndGetUseCount();
             }
             return channel;
         }
@@ -361,12 +391,18 @@
      */
     protected void finalize() throws IOException {
         if ((fd != null) &&  (fd != FileDescriptor.in)) {
-            /* if fd is shared, the references in FileDescriptor
-             * will ensure that finalizer is only called when
-             * safe to do so. All references using the fd have
-             * become unreachable. We can call close()
+
+            /*
+             * Finalizer should not release the FileDescriptor if another
+             * stream is still using it. If the user directly invokes
+             * close() then the FileDescriptor is also released.
              */
-            close();
+            runningFinalize.set(Boolean.TRUE);
+            try {
+                close();
+            } finally {
+                runningFinalize.set(Boolean.FALSE);
+            }
         }
     }
 }
--- a/src/share/classes/java/io/FileOutputStream.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/share/classes/java/io/FileOutputStream.java	Wed Jul 11 20:30:23 2012 -0700
@@ -69,6 +69,15 @@
 
     private final Object closeLock = new Object();
     private volatile boolean closed = false;
+    private static final ThreadLocal<Boolean> runningFinalize =
+        new ThreadLocal<>();
+
+    private static boolean isRunningFinalize() {
+        Boolean val;
+        if ((val = runningFinalize.get()) != null)
+            return val.booleanValue();
+        return false;
+    }
 
     /**
      * Creates a file output stream to write to the file with the
@@ -199,7 +208,7 @@
         this.fd = new FileDescriptor();
         this.append = append;
 
-        fd.attach(this);
+        fd.incrementAndGetUseCount();
         open(name, append);
     }
 
@@ -236,7 +245,13 @@
         }
         this.fd = fdObj;
         this.append = false;
-        fd.attach(this);
+
+        /*
+         * FileDescriptor is being shared by streams.
+         * Ensure that it's GC'ed only when all the streams/channels are done
+         * using it.
+         */
+        fd.incrementAndGetUseCount();
     }
 
     /**
@@ -325,13 +340,27 @@
         }
 
         if (channel != null) {
+            /*
+             * Decrement FD use count associated with the channel
+             * The use count is incremented whenever a new channel
+             * is obtained from this stream.
+             */
+            fd.decrementAndGetUseCount();
             channel.close();
         }
-        fd.closeAll(new Closeable() {
-            public void close() throws IOException {
-               close0();
-           }
-        });
+
+        /*
+         * Decrement FD use count associated with this stream
+         */
+        int useCount = fd.decrementAndGetUseCount();
+
+        /*
+         * If FileDescriptor is still in use by another stream, the finalizer
+         * will not close it.
+         */
+        if ((useCount <= 0) || !isRunningFinalize()) {
+            close0();
+        }
     }
 
     /**
@@ -345,9 +374,7 @@
      * @see        java.io.FileDescriptor
      */
      public final FileDescriptor getFD()  throws IOException {
-        if (fd != null) {
-            return fd;
-        }
+        if (fd != null) return fd;
         throw new IOException();
      }
 
@@ -372,6 +399,13 @@
         synchronized (this) {
             if (channel == null) {
                 channel = FileChannelImpl.open(fd, false, true, append, this);
+
+                /*
+                 * Increment fd's use count. Invoking the channel's close()
+                 * method will result in decrementing the use count set for
+                 * the channel.
+                 */
+                fd.incrementAndGetUseCount();
             }
             return channel;
         }
@@ -390,12 +424,18 @@
             if (fd == FileDescriptor.out || fd == FileDescriptor.err) {
                 flush();
             } else {
-                /* if fd is shared, the references in FileDescriptor
-                 * will ensure that finalizer is only called when
-                 * safe to do so. All references using the fd have
-                 * become unreachable. We can call close()
+
+                /*
+                 * Finalizer should not release the FileDescriptor if another
+                 * stream is still using it. If the user directly invokes
+                 * close() then the FileDescriptor is also released.
                  */
-                close();
+                runningFinalize.set(Boolean.TRUE);
+                try {
+                    close();
+                } finally {
+                    runningFinalize.set(Boolean.FALSE);
+                }
             }
         }
     }
--- a/src/share/classes/java/io/RandomAccessFile.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/share/classes/java/io/RandomAccessFile.java	Wed Jul 11 20:30:23 2012 -0700
@@ -229,7 +229,7 @@
             throw new NullPointerException();
         }
         fd = new FileDescriptor();
-        fd.attach(this);
+        fd.incrementAndGetUseCount();
         open(name, imode);
     }
 
@@ -242,9 +242,7 @@
      * @see        java.io.FileDescriptor
      */
     public final FileDescriptor getFD() throws IOException {
-        if (fd != null) {
-            return fd;
-        }
+        if (fd != null) return fd;
         throw new IOException();
     }
 
@@ -270,6 +268,17 @@
         synchronized (this) {
             if (channel == null) {
                 channel = FileChannelImpl.open(fd, true, rw, this);
+
+                /*
+                 * FileDescriptor could be shared by FileInputStream or
+                 * FileOutputStream.
+                 * Ensure that FD is GC'ed only when all the streams/channels
+                 * are done using it.
+                 * Increment fd's use count. Invoking the channel's close()
+                 * method will result in decrementing the use count set for
+                 * the channel.
+                 */
+                fd.incrementAndGetUseCount();
             }
             return channel;
         }
@@ -568,13 +577,21 @@
             closed = true;
         }
         if (channel != null) {
+            /*
+             * Decrement FD use count associated with the channel. The FD use
+             * count is incremented whenever a new channel is obtained from
+             * this stream.
+             */
+            fd.decrementAndGetUseCount();
             channel.close();
         }
-        fd.closeAll(new Closeable() {
-            public void close() throws IOException {
-               close0();
-           }
-        });
+
+        /*
+         * Decrement FD use count associated with this stream.
+         * The count got incremented by FileDescriptor during its construction.
+         */
+        fd.decrementAndGetUseCount();
+        close0();
     }
 
     //
--- a/src/share/classes/java/util/Hashtable.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/share/classes/java/util/Hashtable.java	Wed Jul 11 20:30:23 2012 -0700
@@ -167,13 +167,13 @@
      * The default threshold of map capacity above which alternative hashing is
      * used for String keys. Alternative hashing reduces the incidence of
      * collisions due to weak hash code calculation for String keys.
-     * <p/>
+     * <p>
      * This value may be overridden by defining the system property
      * {@code jdk.map.althashing.threshold}. A property value of {@code 1}
      * forces alternative hashing to be used at all times whereas
      * {@code -1} value ensures that alternative hashing is never used.
      */
-    static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = 512;
+    static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;
 
     /**
      * holds values which can't be initialized until after VM is booted.
--- a/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java	Wed Jul 11 20:30:23 2012 -0700
@@ -498,7 +498,7 @@
         postDropTargetEvent(component, x, y, dropAction, actions,
                             formats, nativeCtxt,
                             SunDropTargetEvent.MOUSE_DROPPED,
-                            SunDropTargetContextPeer.DISPATCH_SYNC);
+                            !SunDropTargetContextPeer.DISPATCH_SYNC);
     }
 
     /**
--- a/src/solaris/classes/java/io/FileDescriptor.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/solaris/classes/java/io/FileDescriptor.java	Wed Jul 11 20:30:23 2012 -0700
@@ -24,8 +24,8 @@
  */
 
 package java.io;
-import java.util.ArrayList;
-import java.util.List;
+
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Instances of the file descriptor class serve as an opaque handle
@@ -45,9 +45,13 @@
 public final class FileDescriptor {
 
     private int fd;
-    private Closeable parent;
-    private List<Closeable> otherParents;
-    private boolean closed;
+
+    /**
+     * A counter for tracking the FIS/FOS/RAF instances that
+     * use this FileDescriptor. The FIS/FOS.finalize() will not release
+     * the FileDescriptor if it is still under user by a stream.
+     */
+    private AtomicInteger useCount;
 
     /**
      * Constructs an (invalid) FileDescriptor
@@ -55,10 +59,12 @@
      */
     public /**/ FileDescriptor() {
         fd = -1;
+        useCount = new AtomicInteger();
     }
 
     private /* */ FileDescriptor(int fd) {
         this.fd = fd;
+        useCount = new AtomicInteger();
     }
 
     /**
@@ -158,67 +164,13 @@
         );
     }
 
-    /*
-     * Package private methods to track referents.
-     * If multiple streams point to the same FileDescriptor, we cycle
-     * through the list of all referents and call close()
-     */
+    // package private methods used by FIS, FOS and RAF
 
-    /**
-     * Attach a Closeable to this FD for tracking.
-     * parent reference is added to otherParents when
-     * needed to make closeAll simpler.
-     */
-    synchronized void attach(Closeable c) {
-        if (parent == null) {
-            // first caller gets to do this
-            parent = c;
-        } else if (otherParents == null) {
-            otherParents = new ArrayList<>();
-            otherParents.add(parent);
-            otherParents.add(c);
-        } else {
-            otherParents.add(c);
-        }
+    int incrementAndGetUseCount() {
+        return useCount.incrementAndGet();
     }
 
-    /**
-     * Cycle through all Closeables sharing this FD and call
-     * close() on each one.
-     *
-     * The caller closeable gets to call close0().
-     */
-    @SuppressWarnings("try")
-    synchronized void closeAll(Closeable releaser) throws IOException {
-        if (!closed) {
-            closed = true;
-            IOException ioe = null;
-            try (Closeable c = releaser) {
-                if (otherParents != null) {
-                    for (Closeable referent : otherParents) {
-                        try {
-                            referent.close();
-                        } catch(IOException x) {
-                            if (ioe == null) {
-                                ioe = x;
-                            } else {
-                                ioe.addSuppressed(x);
-                            }
-                        }
-                    }
-                }
-            } catch(IOException ex) {
-                /*
-                 * If releaser close() throws IOException
-                 * add other exceptions as suppressed.
-                 */
-                if (ioe != null)
-                    ex.addSuppressed(ioe);
-                ioe = ex;
-            } finally {
-                if (ioe != null)
-                    throw ioe;
-            }
-        }
+    int decrementAndGetUseCount() {
+        return useCount.decrementAndGet();
     }
 }
--- a/src/solaris/doc/sun/man/man1/jcmd.1	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/solaris/doc/sun/man/man1/jcmd.1	Wed Jul 11 20:30:23 2012 -0700
@@ -19,7 +19,7 @@
 ." or visit www.oracle.com if you need additional information or have any
 ." questions.
 ."
-.TH jcmd 1 "16 Mar 2012"
+.TH jcmd 1 "10 Jul 2012"
 
 .LP
 .SH "Name"
@@ -56,7 +56,7 @@
 When a process id is specified on the command line, jcmd sends the diagnostic command request to the process with this id.
 .LP
 .LP
-When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes with this main class.
+When a main class is specified on the command line, jcmd sends the diagnostic command request to all Java processes for which the command line argument is a substring of the Java process' main class.
 .LP
 .LP
 With the PerfCounter.print argument, jcmd prints the performance counters available on the targeted Java process(es).
@@ -73,11 +73,9 @@
 .TP 3
 \-l 
 Prints the list of running Java processes with their process id, their main class and their command line arguments. 
-.br
 .TP 3
 \-h 
 Prints a help message. 
-.br
 .TP 3
 \-help 
 Prints a help message. 
@@ -90,19 +88,15 @@
 .TP 3
 pid 
 Identifies the process that receives the diagnostic command requests. The process must be a Java process. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
-.br
 .TP 3
 main class 
-Main class of the process that receives the diagnostic command requests. If several running Java processes share this main class, the diagnostic command request is sent to all these processes. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
-.br
+Main class of the process that receives the diagnostic command requests. When matching processes, any process whose main class name contains the specified string as a substring will be matched. If several running Java processes share this main class, the diagnostic command request is sent to all these processes. To get a list of Java processes running on a machine, use jps(1) or jcmd(1). 
 .TP 3
 command [arguments] 
-Invoke the diagnostic command called \f2command\fP on the targeted Java process(es). The list of available diagnostic commands for a given process can be obtained by invoking the \f3help\fP command on this process. Each diagnostic command has its own set of \f2arguments\fP, which can be obtained by invoking the \f3help\fP command followed by the command name. 
-.br
+Invoke the diagnostic command called \f2command\fP on the targeted Java process(es). The list of available diagnostic commands for a given process can be obtained by invoking the \f3help\fP command on this process. Each diagnostic command has its own set of \f2arguments\fP, which can be obtained by invoking the the command name followed by \f3help\fP. 
 .TP 3
-Counter.print 
+PerfCounter.print 
 Print the performance counters available on the targeted Java process(es). The list of performance counters may vary with the Java process. 
-.br
 .TP 3
 \-f file 
 Read commands from \f2file\fP and invoke them on the targeted Java process(es). In \f2file\fP, each command must be written on a single line. Lines starting with # are ignored. Processing of \f2file\fP ends when all lines have been invoked or when a line containing the \f3stop\fP keyword is read. 
--- a/src/windows/classes/java/io/FileDescriptor.java	Wed Jul 11 11:23:10 2012 -0700
+++ b/src/windows/classes/java/io/FileDescriptor.java	Wed Jul 11 20:30:23 2012 -0700
@@ -24,8 +24,8 @@
  */
 
 package java.io;
-import java.util.ArrayList;
-import java.util.List;
+
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Instances of the file descriptor class serve as an opaque handle
@@ -42,10 +42,16 @@
 public final class FileDescriptor {
 
     private int fd;
+
     private long handle;
-    private Closeable parent;
-    private List<Closeable> otherParents;
-    private boolean closed;
+
+    /**
+     * A use counter for tracking the FIS/FOS/RAF instances that
+     * use this FileDescriptor. The FIS/FOS.finalize() will not release
+     * the FileDescriptor if it is still under use by any stream.
+     */
+    private AtomicInteger useCount;
+
 
     /**
      * Constructs an (invalid) FileDescriptor
@@ -54,6 +60,7 @@
     public /**/ FileDescriptor() {
         fd = -1;
         handle = -1;
+        useCount = new AtomicInteger();
     }
 
     static {
@@ -161,67 +168,13 @@
         return desc;
     }
 
-    /*
-     * Package private methods to track referents.
-     * If multiple streams point to the same FileDescriptor, we cycle
-     * through the list of all referents and call close()
-     */
+    // package private methods used by FIS, FOS and RAF.
 
-    /**
-     * Attach a Closeable to this FD for tracking.
-     * parent reference is added to otherParents when
-     * needed to make closeAll simpler.
-     */
-    synchronized void attach(Closeable c) {
-        if (parent == null) {
-            // first caller gets to do this
-            parent = c;
-        } else if (otherParents == null) {
-            otherParents = new ArrayList<>();
-            otherParents.add(parent);
-            otherParents.add(c);
-        } else {
-            otherParents.add(c);
-        }
+    int incrementAndGetUseCount() {
+        return useCount.incrementAndGet();
     }
 
-    /**
-     * Cycle through all Closeables sharing this FD and call
-     * close() on each one.
-     *
-     * The caller closeable gets to call close0().
-     */
-    @SuppressWarnings("try")
-    synchronized void closeAll(Closeable releaser) throws IOException {
-        if (!closed) {
-            closed = true;
-            IOException ioe = null;
-            try (Closeable c = releaser) {
-                if (otherParents != null) {
-                    for (Closeable referent : otherParents) {
-                        try {
-                            referent.close();
-                        } catch(IOException x) {
-                            if (ioe == null) {
-                                ioe = x;
-                            } else {
-                                ioe.addSuppressed(x);
-                            }
-                        }
-                    }
-                }
-            } catch(IOException ex) {
-                /*
-                 * If releaser close() throws IOException
-                 * add other exceptions as suppressed.
-                 */
-                if (ioe != null)
-                    ex.addSuppressed(ioe);
-                ioe = ex;
-            } finally {
-                if (ioe != null)
-                    throw ioe;
-            }
-        }
+    int decrementAndGetUseCount() {
+        return useCount.decrementAndGet();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/awt/Frame/HideMaximized/HideMaximized.java	Wed Jul 11 20:30:23 2012 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ * 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.
+ */
+
+/*
+  @test
+  @bug 7177173
+  @summary The maximized state shouldn't be reset upon hiding a frame
+  @author anthony.petrov@oracle.com: area=awt.toplevel
+  @run main HideMaximized
+*/
+
+import java.awt.*;
+
+public class HideMaximized {
+    public static void main(String[] args) {
+        if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
+            // Nothing to test
+            return;
+        }
+
+        // First test a decorated frame
+        Frame frame = new Frame("test");
+        test(frame);
+
+        // Now test an undecorated frames
+        frame = new Frame("undecorated test");
+        frame.setUndecorated(true);
+        test(frame);
+    }
+
+    private static void test(Frame frame) {
+        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+        frame.setVisible(true);
+
+        try { Thread.sleep(1000); } catch (Exception ex) {}
+
+        if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
+            throw new RuntimeException("The maximized state has not been applied");
+        }
+
+        // This will hide the frame, and also clean things up for safe exiting
+        frame.dispose();
+
+        try { Thread.sleep(1000); } catch (Exception ex) {}
+
+        if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
+            throw new RuntimeException("The maximized state has been reset");
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/java/io/FileDescriptor/FileChannelFDTest.java	Wed Jul 11 20:30:23 2012 -0700
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006, 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.
+ *
+ * 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.
+ */
+
+/**
+ *
+ * @test
+ * @bug 6322678
+ * @summary Test for making sure that fd is closed during
+ *          finalization of a stream, when an associated
+ *          file channel is not available
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.nio.channels.*;
+
+public class FileChannelFDTest {
+
+    static byte data[] = new byte[] {48, 49, 50, 51, 52, 53, 54, 55, 56, 57,};
+    static String inFileName = "fd-in-test.txt";
+    static String outFileName = "fd-out-test.txt";
+    static File inFile;
+    static File outFile;
+
+    private static void writeToInFile() throws IOException {
+        FileOutputStream out = new FileOutputStream(inFile);
+        out.write(data);
+        out.close();
+    }
+
+    public static void main(String[] args)
+                throws Exception {
+
+        inFile= new File(System.getProperty("test.dir", "."),
+                        inFileName);
+        inFile.createNewFile();
+        inFile.deleteOnExit();
+        writeToInFile();
+
+        outFile  = new File(System.getProperty("test.dir", "."),
+                        outFileName);
+        outFile.createNewFile();
+        outFile.deleteOnExit();
+
+        doFileChannel();
+    }
+
+     private static void doFileChannel() throws Exception {
+
+        FileInputStream fis = new FileInputStream(inFile);
+        FileDescriptor fd = fis.getFD();
+        FileChannel fc = fis.getChannel();
+        System.out.println("Created fis:" + fis);
+
+        /**
+         * Encourage the GC
+         */
+        fis = null;
+        fc = null;
+        System.gc();
+        Thread.sleep(500);
+
+        if (fd.valid()) {
+            throw new Exception("Finalizer either didn't run --" +
+                "try increasing the Thread's sleep time after System.gc();" +
+                "or the finalizer didn't close the file");
+        }
+
+        System.out.println("File Closed successfully");
+        System.out.println();
+  }
+}
--- a/test/java/io/FileDescriptor/Sharing.java	Wed Jul 11 11:23:10 2012 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/*
- * 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.
- *
- * 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.
- */
-
-/*
- * @test
- * @bug 7105952 6322678 7082769
- * @summary Improve finalisation for FileInputStream/FileOutputStream/RandomAccessFile
- * @run main/othervm Sharing
- */
-
-import java.io.*;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.util.concurrent.CountDownLatch;
-
-public class Sharing {
-
-    final static int numFiles = 10;
-    volatile static boolean fail;
-
-    public static void main(String[] args) throws Exception {
-        TestFinalizer();
-        TestMultipleFD();
-        TestIsValid();
-        MultiThreadedFD();
-        TestCloseAll();
-    }
-
-    /**
-     * Finalizer shouldn't discard a file descriptor until all streams have
-     * finished with it.
-     */
-    private static void TestFinalizer() throws Exception {
-        FileDescriptor fd = null;
-        File tempFile = new File("TestFinalizer1.txt");
-        tempFile.deleteOnExit();
-        try (Writer writer = new FileWriter(tempFile)) {
-            for (int i=0; i<5; i++) {
-                writer.write("test file content test file content");
-            }
-        }
-
-        FileInputStream fis1 = new FileInputStream(tempFile);
-        fd = fis1.getFD();
-        // Create a new FIS based on the existing FD (so the two FIS's share the same native fd)
-        try (FileInputStream fis2 = new FileInputStream(fd)) {
-            // allow fis1 to be gc'ed
-            fis1 = null;
-            int ret = 0;
-            while(ret >= 0) {
-                // encourage gc
-                System.gc();
-                // read from fis2 - when fis1 is gc'ed and finalizer is run, read will fail
-                System.out.print(".");
-                ret = fis2.read();
-            }
-        }
-
-        // variation of above. Use RandomAccessFile to obtain a filedescriptor
-        File testFinalizerFile = new File("TestFinalizer");
-        RandomAccessFile raf = new RandomAccessFile(testFinalizerFile, "rw");
-        raf.writeBytes("test file content test file content");
-        raf.seek(0L);
-        fd = raf.getFD();
-        try (FileInputStream fis3 = new FileInputStream(fd)) {
-            // allow raf to be gc'ed
-            raf = null;
-            int ret = 0;
-            while (ret >= 0) {
-                // encourage gc
-                System.gc();
-                /*
-                 * read from fis3 - when raf is gc'ed and finalizer is run,
-                 * fd should still be valid.
-                 */
-                System.out.print(".");
-                ret = fis3.read();
-            }
-        } finally {
-            testFinalizerFile.delete();
-        }
-    }
-
-    /**
-     * Exercise FileDispatcher close()/preClose()
-     */
-    private static void TestMultipleFD() throws Exception {
-        RandomAccessFile raf = null;
-        FileOutputStream fos = null;
-        FileInputStream fis = null;
-        FileChannel fc = null;
-        FileLock fileLock = null;
-
-        File test1 = new File("test1");
-        try {
-            raf = new RandomAccessFile(test1, "rw");
-            fos = new FileOutputStream(raf.getFD());
-            fis = new FileInputStream(raf.getFD());
-            fc = raf.getChannel();
-            fileLock = fc.lock();
-            raf.setLength(0L);
-            fos.flush();
-            fos.write("TEST".getBytes());
-        } finally {
-            if (fileLock != null) fileLock.release();
-            if (fis != null) fis.close();
-            if (fos != null) fos.close();
-            if (raf != null) raf.close();
-            test1.delete();
-        }
-
-        /*
-         * Close out in different order to ensure FD is not
-         * closed out too early
-         */
-        File test2 = new File("test2");
-        try {
-            raf = new RandomAccessFile(test2, "rw");
-            fos = new FileOutputStream(raf.getFD());
-            fis = new FileInputStream(raf.getFD());
-            fc = raf.getChannel();
-            fileLock = fc.lock();
-            raf.setLength(0L);
-            fos.flush();
-            fos.write("TEST".getBytes());
-        } finally {
-            if (fileLock != null) fileLock.release();
-            if (raf != null) raf.close();
-            if (fos != null) fos.close();
-            if (fis != null) fis.close();
-            test2.delete();
-        }
-
-        // one more time, fos first this time
-        File test3 = new File("test3");
-        try {
-            raf = new RandomAccessFile(test3, "rw");
-            fos = new FileOutputStream(raf.getFD());
-            fis = new FileInputStream(raf.getFD());
-            fc = raf.getChannel();
-            fileLock = fc.lock();
-            raf.setLength(0L);
-            fos.flush();
-            fos.write("TEST".getBytes());
-        } finally {
-            if (fileLock != null) fileLock.release();
-            if (fos != null) fos.close();
-            if (raf != null) raf.close();
-            if (fis != null) fis.close();
-            test3.delete();
-        }
-    }
-
-    /**
-     * Similar to TestMultipleFD() but this time we
-     * just get and use FileDescriptor.valid() for testing.
-     */
-    private static void TestIsValid() throws Exception {
-        FileDescriptor fd = null;
-        RandomAccessFile raf = null;
-        FileOutputStream fos = null;
-        FileInputStream fis = null;
-        FileChannel fc = null;
-
-        File test1 = new File("test1");
-        try {
-            raf = new RandomAccessFile(test1, "rw");
-            fd = raf.getFD();
-            fos = new FileOutputStream(fd);
-            fis = new FileInputStream(fd);
-        } finally {
-            try {
-                if (fis != null) fis.close();
-                if (fd.valid()) {
-                    throw new RuntimeException("[FIS close()] FileDescriptor shouldn't be valid");
-                }
-                if (fos != null) fos.close();
-                if (raf != null) raf.close();
-            } finally {
-                test1.delete();
-            }
-        }
-
-        /*
-         * Close out in different order to ensure FD is
-         * closed correctly.
-         */
-        File test2 = new File("test2");
-        try {
-            raf = new RandomAccessFile(test2, "rw");
-            fd = raf.getFD();
-            fos = new FileOutputStream(fd);
-            fis = new FileInputStream(fd);
-        } finally {
-            try {
-                if (raf != null) raf.close();
-                if (fd.valid()) {
-                    throw new RuntimeException("[RAF close()] FileDescriptor shouldn't be valid");
-                }
-                if (fos != null) fos.close();
-                if (fis != null) fis.close();
-            } finally {
-                test2.delete();
-            }
-        }
-
-        // one more time, fos first this time
-        File test3 = new File("test3");
-        try {
-            raf = new RandomAccessFile(test3, "rw");
-            fd = raf.getFD();
-            fos = new FileOutputStream(fd);
-            fis = new FileInputStream(fd);
-        } finally {
-            try {
-                if (fos != null) fos.close();
-                if (fd.valid()) {
-                    throw new RuntimeException("[FOS close()] FileDescriptor shouldn't be valid");
-                }
-                if (raf != null) raf.close();
-                if (fis != null) fis.close();
-            } finally {
-                test3.delete();
-            }
-        }
-    }
-
-    /**
-     * Test concurrent access to the same FileDescriptor
-     */
-    private static void MultiThreadedFD() throws Exception {
-        RandomAccessFile raf = null;
-        FileDescriptor fd = null;
-        int numThreads = 2;
-        CountDownLatch done = new CountDownLatch(numThreads);
-        OpenClose[] fileOpenClose = new OpenClose[numThreads];
-        File MultipleThreadedFD = new File("MultipleThreadedFD");
-        try {
-            raf = new RandomAccessFile(MultipleThreadedFD, "rw");
-            fd = raf.getFD();
-            for(int count=0;count<numThreads;count++) {
-                fileOpenClose[count] = new OpenClose(fd, done);
-                fileOpenClose[count].start();
-            }
-            done.await();
-        } finally {
-            try {
-                if(raf != null) raf.close();
-                // fd should now no longer be valid
-                if(fd.valid()) {
-                    throw new RuntimeException("FileDescriptor should not be valid");
-                }
-                // OpenClose thread tests failed
-                if(fail) {
-                    throw new RuntimeException("OpenClose thread tests failed.");
-                }
-            } finally {
-                MultipleThreadedFD.delete();
-            }
-        }
-    }
-
-    /**
-     * Test closeAll handling in FileDescriptor
-     */
-    private static void TestCloseAll() throws Exception {
-        File testFile = new File("test");
-        testFile.deleteOnExit();
-        RandomAccessFile raf = new RandomAccessFile(testFile, "rw");
-        FileInputStream fis = new FileInputStream(raf.getFD());
-        fis.close();
-        if (raf.getFD().valid()) {
-             throw new RuntimeException("FD should not be valid.");
-        }
-
-        // Test the suppressed exception handling - FileInputStream
-
-        raf = new RandomAccessFile(testFile, "rw");
-        fis = new FileInputStream(raf.getFD());
-        BadFileInputStream bfis1 = new BadFileInputStream(raf.getFD());
-        BadFileInputStream bfis2 = new BadFileInputStream(raf.getFD());
-        BadFileInputStream bfis3 = new BadFileInputStream(raf.getFD());
-        // extra test - set bfis3 to null
-        bfis3 = null;
-        try {
-            fis.close();
-        } catch (IOException ioe) {
-            ioe.printStackTrace();
-            if (ioe.getSuppressed().length != 2) {
-                throw new RuntimeException("[FIS]Incorrect number of suppressed " +
-                          "exceptions received : " + ioe.getSuppressed().length);
-            }
-        }
-        if (raf.getFD().valid()) {
-            // we should still have closed the FD
-            // even with the exception.
-            throw new RuntimeException("[FIS]TestCloseAll : FD still valid.");
-        }
-
-        // Now test with FileOutputStream
-
-        raf = new RandomAccessFile(testFile, "rw");
-        FileOutputStream fos = new FileOutputStream(raf.getFD());
-        BadFileOutputStream bfos1 = new BadFileOutputStream(raf.getFD());
-        BadFileOutputStream bfos2 = new BadFileOutputStream(raf.getFD());
-        BadFileOutputStream bfos3 = new BadFileOutputStream(raf.getFD());
-        // extra test - set bfos3 to null
-        bfos3 = null;
-        try {
-            fos.close();
-        } catch (IOException ioe) {
-            ioe.printStackTrace();
-            if (ioe.getSuppressed().length != 2) {
-                throw new RuntimeException("[FOS]Incorrect number of suppressed " +
-                          "exceptions received : " + ioe.getSuppressed().length);
-            }
-        }
-        if (raf.getFD().valid()) {
-            // we should still have closed the FD
-            // even with the exception.
-            throw new RuntimeException("[FOS]TestCloseAll : FD still valid.");
-        }
-    }
-
-    /**
-     * A thread which will open and close a number of FileInputStreams and
-     * FileOutputStreams referencing the same native file descriptor.
-     */
-    private static class OpenClose extends Thread {
-        private FileDescriptor fd = null;
-        private CountDownLatch done;
-        FileInputStream[] fisArray = new FileInputStream[numFiles];
-        FileOutputStream[] fosArray = new FileOutputStream[numFiles];
-
-        OpenClose(FileDescriptor filedescriptor, CountDownLatch done) {
-            this.fd = filedescriptor;
-            this.done = done;
-        }
-
-        public void run() {
-             try {
-                 for(int i=0;i<numFiles;i++) {
-                     fisArray[i] = new FileInputStream(fd);
-                     fosArray[i] = new FileOutputStream(fd);
-                 }
-
-                 // Now close out
-                 for(int i=0;i<numFiles;i++) {
-                     if(fisArray[i] != null) fisArray[i].close();
-                     if(fosArray[i] != null) fosArray[i].close();
-                 }
-
-             } catch(IOException ioe) {
-                 System.out.println("OpenClose encountered IO issue :" + ioe);
-                 fail = true;
-             } finally {
-                 if (fd.valid()) { // fd should not be valid after first close() call
-                     System.out.println("OpenClose: FileDescriptor shouldn't be valid");
-                     fail = true;
-                 }
-                 done.countDown();
-             }
-         }
-    }
-
-    private static class BadFileInputStream extends FileInputStream {
-
-        BadFileInputStream(FileDescriptor fd) {
-            super(fd);
-        }
-
-        public void close() throws IOException {
-            throw new IOException("Bad close operation");
-        }
-    }
-
-    private static class BadFileOutputStream extends FileOutputStream {
-
-        BadFileOutputStream(FileDescriptor fd) {
-            super(fd);
-        }
-
-        public void close() throws IOException {
-            throw new IOException("Bad close operation");
-        }
-    }
-
-}