Merge
authortbell
Mon, 04 May 2009 22:16:02 -0700
changeset 1192b3720710a4ba
parent 1178 b056c42ea5b4
parent 1191 e1a713f0361f
child 1193 d201987cb76c
Merge
     1.1 --- a/src/share/classes/java/io/Console.java	Mon May 04 18:28:26 2009 -0700
     1.2 +++ b/src/share/classes/java/io/Console.java	Mon May 04 22:16:02 2009 -0700
     1.3 @@ -503,20 +503,25 @@
     1.4  
     1.5      // Set up JavaIOAccess in SharedSecrets
     1.6      static {
     1.7 -
     1.8 -        // Add a shutdown hook to restore console's echo state should
     1.9 -        // it be necessary.
    1.10 -        sun.misc.SharedSecrets.getJavaLangAccess()
    1.11 -            .registerShutdownHook(0 /* shutdown hook invocation order */,
    1.12 -                new Runnable() {
    1.13 -                    public void run() {
    1.14 -                        try {
    1.15 -                            if (echoOff) {
    1.16 -                                echo(true);
    1.17 -                            }
    1.18 -                        } catch (IOException x) { }
    1.19 -                    }
    1.20 -                });
    1.21 +        try {
    1.22 +            // Add a shutdown hook to restore console's echo state should
    1.23 +            // it be necessary.
    1.24 +            sun.misc.SharedSecrets.getJavaLangAccess()
    1.25 +                .registerShutdownHook(0 /* shutdown hook invocation order */,
    1.26 +                    false /* only register if shutdown is not in progress */,
    1.27 +                    new Runnable() {
    1.28 +                        public void run() {
    1.29 +                            try {
    1.30 +                                if (echoOff) {
    1.31 +                                    echo(true);
    1.32 +                                }
    1.33 +                            } catch (IOException x) { }
    1.34 +                        }
    1.35 +                    });
    1.36 +        } catch (IllegalStateException e) {
    1.37 +            // shutdown is already in progress and console is first used
    1.38 +            // by a shutdown hook
    1.39 +        }
    1.40  
    1.41          sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
    1.42              public Console console() {
     2.1 --- a/src/share/classes/java/io/DeleteOnExitHook.java	Mon May 04 18:28:26 2009 -0700
     2.2 +++ b/src/share/classes/java/io/DeleteOnExitHook.java	Mon May 04 22:16:02 2009 -0700
     2.3 @@ -34,23 +34,31 @@
     2.4   */
     2.5  
     2.6  class DeleteOnExitHook {
     2.7 +    private static LinkedHashSet<String> files = new LinkedHashSet<String>();
     2.8      static {
     2.9 -         sun.misc.SharedSecrets.getJavaLangAccess()
    2.10 -             .registerShutdownHook(2 /* Shutdown hook invocation order */,
    2.11 -                 new Runnable() {
    2.12 -                     public void run() {
    2.13 -                        runHooks();
    2.14 -                     }
    2.15 -                 });
    2.16 +        // DeleteOnExitHook must be the last shutdown hook to be invoked.
    2.17 +        // Application shutdown hooks may add the first file to the
    2.18 +        // delete on exit list and cause the DeleteOnExitHook to be
    2.19 +        // registered during shutdown in progress. So set the
    2.20 +        // registerShutdownInProgress parameter to true.
    2.21 +        sun.misc.SharedSecrets.getJavaLangAccess()
    2.22 +            .registerShutdownHook(2 /* Shutdown hook invocation order */,
    2.23 +                true /* register even if shutdown in progress */,
    2.24 +                new Runnable() {
    2.25 +                    public void run() {
    2.26 +                       runHooks();
    2.27 +                    }
    2.28 +                }
    2.29 +        );
    2.30      }
    2.31  
    2.32 -    private static LinkedHashSet<String> files = new LinkedHashSet<String>();
    2.33 -
    2.34      private DeleteOnExitHook() {}
    2.35  
    2.36      static synchronized void add(String file) {
    2.37 -        if(files == null)
    2.38 +        if(files == null) {
    2.39 +            // DeleteOnExitHook is running. Too late to add a file
    2.40              throw new IllegalStateException("Shutdown in progress");
    2.41 +        }
    2.42  
    2.43          files.add(file);
    2.44      }
     3.1 --- a/src/share/classes/java/lang/ApplicationShutdownHooks.java	Mon May 04 18:28:26 2009 -0700
     3.2 +++ b/src/share/classes/java/lang/ApplicationShutdownHooks.java	Mon May 04 22:16:02 2009 -0700
     3.3 @@ -35,17 +35,26 @@
     3.4   */
     3.5  
     3.6  class ApplicationShutdownHooks {
     3.7 +    /* The set of registered hooks */
     3.8 +    private static IdentityHashMap<Thread, Thread> hooks;
     3.9      static {
    3.10 -        Shutdown.add(1 /* shutdown hook invocation order */,
    3.11 -            new Runnable() {
    3.12 -                public void run() {
    3.13 -                    runHooks();
    3.14 +        try {
    3.15 +            Shutdown.add(1 /* shutdown hook invocation order */,
    3.16 +                false /* not registered if shutdown in progress */,
    3.17 +                new Runnable() {
    3.18 +                    public void run() {
    3.19 +                        runHooks();
    3.20 +                    }
    3.21                  }
    3.22 -            });
    3.23 +            );
    3.24 +            hooks = new IdentityHashMap<Thread, Thread>();
    3.25 +        } catch (IllegalStateException e) {
    3.26 +            // application shutdown hooks cannot be added if
    3.27 +            // shutdown is in progress.
    3.28 +            hooks = null;
    3.29 +        }
    3.30      }
    3.31  
    3.32 -    /* The set of registered hooks */
    3.33 -    private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
    3.34  
    3.35      private ApplicationShutdownHooks() {}
    3.36  
     4.1 --- a/src/share/classes/java/lang/Shutdown.java	Mon May 04 18:28:26 2009 -0700
     4.2 +++ b/src/share/classes/java/lang/Shutdown.java	Mon May 04 22:16:02 2009 -0700
     4.3 @@ -53,6 +53,9 @@
     4.4      private static final int MAX_SYSTEM_HOOKS = 10;
     4.5      private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
     4.6  
     4.7 +    // the index of the currently running shutdown hook to the hooks array
     4.8 +    private static int currentRunningHook = 0;
     4.9 +
    4.10      /* The preceding static fields are protected by this lock */
    4.11      private static class Lock { };
    4.12      private static Object lock = new Lock();
    4.13 @@ -68,17 +71,39 @@
    4.14      }
    4.15  
    4.16  
    4.17 -    /* Add a new shutdown hook.  Checks the shutdown state and the hook itself,
    4.18 +    /**
    4.19 +     * Add a new shutdown hook.  Checks the shutdown state and the hook itself,
    4.20       * but does not do any security checks.
    4.21 +     *
    4.22 +     * The registerShutdownInProgress parameter should be false except
    4.23 +     * registering the DeleteOnExitHook since the first file may
    4.24 +     * be added to the delete on exit list by the application shutdown
    4.25 +     * hooks.
    4.26 +     *
    4.27 +     * @params slot  the slot in the shutdown hook array, whose element
    4.28 +     *               will be invoked in order during shutdown
    4.29 +     * @params registerShutdownInProgress true to allow the hook
    4.30 +     *               to be registered even if the shutdown is in progress.
    4.31 +     * @params hook  the hook to be registered
    4.32 +     *
    4.33 +     * @throw IllegalStateException
    4.34 +     *        if registerShutdownInProgress is false and shutdown is in progress; or
    4.35 +     *        if registerShutdownInProgress is true and the shutdown process
    4.36 +     *           already passes the given slot
    4.37       */
    4.38 -    static void add(int slot, Runnable hook) {
    4.39 +    static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
    4.40          synchronized (lock) {
    4.41 -            if (state > RUNNING)
    4.42 -                throw new IllegalStateException("Shutdown in progress");
    4.43 -
    4.44              if (hooks[slot] != null)
    4.45                  throw new InternalError("Shutdown hook at slot " + slot + " already registered");
    4.46  
    4.47 +            if (!registerShutdownInProgress) {
    4.48 +                if (state > RUNNING)
    4.49 +                    throw new IllegalStateException("Shutdown in progress");
    4.50 +            } else {
    4.51 +                if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
    4.52 +                    throw new IllegalStateException("Shutdown in progress");
    4.53 +            }
    4.54 +
    4.55              hooks[slot] = hook;
    4.56          }
    4.57      }
    4.58 @@ -86,11 +111,15 @@
    4.59      /* Run all registered shutdown hooks
    4.60       */
    4.61      private static void runHooks() {
    4.62 -        /* We needn't bother acquiring the lock just to read the hooks field,
    4.63 -         * since the hooks can't be modified once shutdown is in progress
    4.64 -         */
    4.65 -        for (Runnable hook : hooks) {
    4.66 +        for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
    4.67              try {
    4.68 +                Runnable hook;
    4.69 +                synchronized (lock) {
    4.70 +                    // acquire the lock to make sure the hook registered during
    4.71 +                    // shutdown is visible here.
    4.72 +                    currentRunningHook = i;
    4.73 +                    hook = hooks[i];
    4.74 +                }
    4.75                  if (hook != null) hook.run();
    4.76              } catch(Throwable t) {
    4.77                  if (t instanceof ThreadDeath) {
     5.1 --- a/src/share/classes/java/lang/System.java	Mon May 04 18:28:26 2009 -0700
     5.2 +++ b/src/share/classes/java/lang/System.java	Mon May 04 22:16:02 2009 -0700
     5.3 @@ -1171,8 +1171,8 @@
     5.4              public void blockedOn(Thread t, Interruptible b) {
     5.5                  t.blockedOn(b);
     5.6              }
     5.7 -            public void registerShutdownHook(int slot, Runnable r) {
     5.8 -                Shutdown.add(slot, r);
     5.9 +            public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
    5.10 +                Shutdown.add(slot, registerShutdownInProgress, hook);
    5.11              }
    5.12          });
    5.13      }
     6.1 --- a/src/share/classes/java/util/zip/ZipFile.java	Mon May 04 18:28:26 2009 -0700
     6.2 +++ b/src/share/classes/java/util/zip/ZipFile.java	Mon May 04 22:16:02 2009 -0700
     6.3 @@ -154,7 +154,7 @@
     6.4       * @param file the ZIP file to be opened for reading
     6.5       * @param mode the mode in which the file is to be opened
     6.6       * @param charset
     6.7 -     *        the {@link java.nio.charset.Charset {@code charset}} to
     6.8 +     *        the {@linkplain java.nio.charset.Charset charset} to
     6.9       *        be used to decode the ZIP entry name and comment that are not
    6.10       *        encoded by using UTF-8 encoding (indicated by entry's general
    6.11       *        purpose flag).
    6.12 @@ -206,7 +206,7 @@
    6.13       *
    6.14       * @param name the name of the zip file
    6.15       * @param charset
    6.16 -     *        the {@link java.nio.charset.Charset {@code charset}} to
    6.17 +     *        the {@linkplain java.nio.charset.Charset charset} to
    6.18       *        be used to decode the ZIP entry name and comment that are not
    6.19       *        encoded by using UTF-8 encoding (indicated by entry's general
    6.20       *        purpose flag).
    6.21 @@ -230,7 +230,7 @@
    6.22       * Opens a ZIP file for reading given the specified File object.
    6.23       * @param file the ZIP file to be opened for reading
    6.24       * @param charset
    6.25 -     *        The {@link java.nio.charset.Charset {@code charset}} to be
    6.26 +     *        The {@linkplain java.nio.charset.Charset charset} to be
    6.27       *        used to decode the ZIP entry name and comment (ignored if
    6.28       *        the <a href="package-summary.html#lang_encoding"> language
    6.29       *        encoding bit</a> of the ZIP entry's general purpose bit
     7.1 --- a/src/share/classes/java/util/zip/ZipInputStream.java	Mon May 04 18:28:26 2009 -0700
     7.2 +++ b/src/share/classes/java/util/zip/ZipInputStream.java	Mon May 04 22:16:02 2009 -0700
     7.3 @@ -84,7 +84,7 @@
     7.4       * @param in the actual input stream
     7.5       *
     7.6       * @param charset
     7.7 -     *        The {@link java.nio.charset.Charset {@code charset}} to be
     7.8 +     *        The {@linkplain java.nio.charset.Charset charset} to be
     7.9       *        used to decode the ZIP entry name (ignored if the
    7.10       *        <a href="package-summary.html#lang_encoding"> language
    7.11       *        encoding bit</a> of the ZIP entry's general purpose bit
     8.1 --- a/src/share/classes/java/util/zip/ZipOutputStream.java	Mon May 04 18:28:26 2009 -0700
     8.2 +++ b/src/share/classes/java/util/zip/ZipOutputStream.java	Mon May 04 22:16:02 2009 -0700
     8.3 @@ -108,7 +108,7 @@
     8.4       *
     8.5       * @param out the actual output stream
     8.6       *
     8.7 -     * @param charset the {@link java.nio.charset.Charset </code>charset<code>}
     8.8 +     * @param charset the {@linkplain java.nio.charset.Charset charset}
     8.9       *                to be used to encode the entry names and comments
    8.10       *
    8.11       * @since 1.7
     9.1 --- a/src/share/classes/sun/misc/JavaLangAccess.java	Mon May 04 18:28:26 2009 -0700
     9.2 +++ b/src/share/classes/sun/misc/JavaLangAccess.java	Mon May 04 22:16:02 2009 -0700
     9.3 @@ -55,6 +55,22 @@
     9.4      /** Set thread's blocker field. */
     9.5      void blockedOn(Thread t, Interruptible b);
     9.6  
     9.7 -    /** register shutdown hook */
     9.8 -    void registerShutdownHook(int slot, Runnable r);
     9.9 +    /**
    9.10 +     * Registers a shutdown hook.
    9.11 +     *
    9.12 +     * It is expected that this method with registerShutdownInProgress=true
    9.13 +     * is only used to register DeleteOnExitHook since the first file
    9.14 +     * may be added to the delete on exit list by the application shutdown
    9.15 +     * hooks.
    9.16 +     *
    9.17 +     * @params slot  the slot in the shutdown hook array, whose element
    9.18 +     *               will be invoked in order during shutdown
    9.19 +     * @params registerShutdownInProgress true to allow the hook
    9.20 +     *               to be registered even if the shutdown is in progress.
    9.21 +     * @params hook  the hook to be registered
    9.22 +     *
    9.23 +     * @throw IllegalStateException if shutdown is in progress and
    9.24 +     *          the slot is not valid to register.
    9.25 +     */
    9.26 +    void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
    9.27  }
    10.1 --- a/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Mon May 04 18:28:26 2009 -0700
    10.2 +++ b/src/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java	Mon May 04 22:16:02 2009 -0700
    10.3 @@ -475,49 +475,40 @@
    10.4                  // get an OVERLAPPED structure (from the cache or allocate)
    10.5                  overlapped = ioCache.add(result);
    10.6  
    10.7 -                // synchronize on result to allow this thread handle the case
    10.8 -                // where the read completes immediately.
    10.9 -                synchronized (result) {
   10.10 -                    int n = read0(handle, numBufs, readBufferArray, overlapped);
   10.11 -                    if (n == IOStatus.UNAVAILABLE) {
   10.12 -                        // I/O is pending
   10.13 -                        pending = true;
   10.14 -                        return;
   10.15 +                // initiate read
   10.16 +                int n = read0(handle, numBufs, readBufferArray, overlapped);
   10.17 +                if (n == IOStatus.UNAVAILABLE) {
   10.18 +                    // I/O is pending
   10.19 +                    pending = true;
   10.20 +                    return;
   10.21 +                }
   10.22 +                if (n == IOStatus.EOF) {
   10.23 +                    // input shutdown
   10.24 +                    enableReading();
   10.25 +                    if (scatteringRead) {
   10.26 +                        result.setResult((V)Long.valueOf(-1L));
   10.27 +                    } else {
   10.28 +                        result.setResult((V)Integer.valueOf(-1));
   10.29                      }
   10.30 -                    // read completed immediately:
   10.31 -                    // 1. update buffer position
   10.32 -                    // 2. reset read flag
   10.33 -                    // 3. release waiters
   10.34 -                    if (n == 0) {
   10.35 -                        n = -1;
   10.36 -                    } else {
   10.37 -                        updateBuffers(n);
   10.38 -                    }
   10.39 -                    enableReading();
   10.40 -
   10.41 -                    if (scatteringRead) {
   10.42 -                        result.setResult((V)Long.valueOf(n));
   10.43 -                    } else {
   10.44 -                        result.setResult((V)Integer.valueOf(n));
   10.45 -                    }
   10.46 +                } else {
   10.47 +                    throw new InternalError("Read completed immediately");
   10.48                  }
   10.49              } catch (Throwable x) {
   10.50 -                // failed to initiate read:
   10.51 -                // 1. reset read flag
   10.52 -                // 2. free resources
   10.53 -                // 3. release waiters
   10.54 +                // failed to initiate read
   10.55 +                // reset read flag before releasing waiters
   10.56                  enableReading();
   10.57 -                if (overlapped != 0L)
   10.58 -                    ioCache.remove(overlapped);
   10.59                  if (x instanceof ClosedChannelException)
   10.60                      x = new AsynchronousCloseException();
   10.61                  if (!(x instanceof IOException))
   10.62                      x = new IOException(x);
   10.63                  result.setFailure(x);
   10.64              } finally {
   10.65 -                if (prepared && !pending) {
   10.66 -                    // return direct buffer(s) to cache if substituted
   10.67 -                    releaseBuffers();
   10.68 +                // release resources if I/O not pending
   10.69 +                if (!pending) {
   10.70 +                    if (overlapped != 0L)
   10.71 +                        ioCache.remove(overlapped);
   10.72 +                    if (prepared)
   10.73 +                        releaseBuffers();
   10.74                  }
   10.75                  end();
   10.76              }
   10.77 @@ -721,7 +712,6 @@
   10.78          @Override
   10.79          @SuppressWarnings("unchecked")
   10.80          public void run() {
   10.81 -            int n = -1;
   10.82              long overlapped = 0L;
   10.83              boolean prepared = false;
   10.84              boolean pending = false;
   10.85 @@ -736,56 +726,34 @@
   10.86  
   10.87                  // get an OVERLAPPED structure (from the cache or allocate)
   10.88                  overlapped = ioCache.add(result);
   10.89 -
   10.90 -                // synchronize on result to allow this thread handle the case
   10.91 -                // where the read completes immediately.
   10.92 -                synchronized (result) {
   10.93 -                    n = write0(handle, numBufs, writeBufferArray, overlapped);
   10.94 -                    if (n == IOStatus.UNAVAILABLE) {
   10.95 -                        // I/O is pending
   10.96 -                        pending = true;
   10.97 -                        return;
   10.98 -                    }
   10.99 -
  10.100 -                    enableWriting();
  10.101 -
  10.102 -                    if (n == IOStatus.EOF) {
  10.103 -                        // special case for shutdown output
  10.104 -                        shutdown = true;
  10.105 -                        throw new ClosedChannelException();
  10.106 -                    }
  10.107 -
  10.108 -                    // write completed immediately:
  10.109 -                    // 1. enable writing
  10.110 -                    // 2. update buffer position
  10.111 -                    // 3. release waiters
  10.112 -                    updateBuffers(n);
  10.113 -
  10.114 -                    // result is a Long or Integer
  10.115 -                    if (gatheringWrite) {
  10.116 -                        result.setResult((V)Long.valueOf(n));
  10.117 -                    } else {
  10.118 -                        result.setResult((V)Integer.valueOf(n));
  10.119 -                    }
  10.120 +                int n = write0(handle, numBufs, writeBufferArray, overlapped);
  10.121 +                if (n == IOStatus.UNAVAILABLE) {
  10.122 +                    // I/O is pending
  10.123 +                    pending = true;
  10.124 +                    return;
  10.125                  }
  10.126 +                if (n == IOStatus.EOF) {
  10.127 +                    // special case for shutdown output
  10.128 +                    shutdown = true;
  10.129 +                    throw new ClosedChannelException();
  10.130 +                }
  10.131 +                // write completed immediately
  10.132 +                throw new InternalError("Write completed immediately");
  10.133              } catch (Throwable x) {
  10.134 +                // write failed. Enable writing before releasing waiters.
  10.135                  enableWriting();
  10.136 -
  10.137 -                // failed to initiate read:
  10.138                  if (!shutdown && (x instanceof ClosedChannelException))
  10.139                      x = new AsynchronousCloseException();
  10.140                  if (!(x instanceof IOException))
  10.141                      x = new IOException(x);
  10.142                  result.setFailure(x);
  10.143 -
  10.144 -                // release resources
  10.145 -                if (overlapped != 0L)
  10.146 -                    ioCache.remove(overlapped);
  10.147 -
  10.148              } finally {
  10.149 -                if (prepared && !pending) {
  10.150 -                    // return direct buffer(s) to cache if substituted
  10.151 -                    releaseBuffers();
  10.152 +                // release resources if I/O not pending
  10.153 +                if (!pending) {
  10.154 +                    if (overlapped != 0L)
  10.155 +                        ioCache.remove(overlapped);
  10.156 +                    if (prepared)
  10.157 +                        releaseBuffers();
  10.158                  }
  10.159                  end();
  10.160              }
    11.1 --- a/src/windows/native/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.c	Mon May 04 18:28:26 2009 -0700
    11.2 +++ b/src/windows/native/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.c	Mon May 04 22:16:02 2009 -0700
    11.3 @@ -157,14 +157,13 @@
    11.4      WSABUF* lpWsaBuf = (WSABUF*) jlong_to_ptr(address);
    11.5      OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
    11.6      BOOL res;
    11.7 -    DWORD nread = 0;
    11.8      DWORD flags = 0;
    11.9  
   11.10      ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
   11.11      res = WSARecv(s,
   11.12                    lpWsaBuf,
   11.13                    (DWORD)count,
   11.14 -                  &nread,
   11.15 +                  NULL,
   11.16                    &flags,
   11.17                    lpOverlapped,
   11.18                    NULL);
   11.19 @@ -175,17 +174,12 @@
   11.20              return IOS_UNAVAILABLE;
   11.21          }
   11.22          if (error == WSAESHUTDOWN) {
   11.23 -            return 0;       // input shutdown
   11.24 +            return IOS_EOF;       // input shutdown
   11.25          }
   11.26          JNU_ThrowIOExceptionWithLastError(env, "WSARecv failed");
   11.27          return IOS_THROWN;
   11.28      }
   11.29 -    if (nread == 0) {
   11.30 -        // Handle graceful close or bytes not yet available cases
   11.31 -        // via completion port notification.
   11.32 -        return IOS_UNAVAILABLE;
   11.33 -    }
   11.34 -    return (jint)nread;
   11.35 +    return IOS_UNAVAILABLE;
   11.36  }
   11.37  
   11.38  JNIEXPORT jint JNICALL
   11.39 @@ -196,13 +190,12 @@
   11.40      WSABUF* lpWsaBuf = (WSABUF*) jlong_to_ptr(address);
   11.41      OVERLAPPED* lpOverlapped = (OVERLAPPED*) jlong_to_ptr(ov);
   11.42      BOOL res;
   11.43 -    DWORD nwritten;
   11.44  
   11.45      ZeroMemory((PVOID)lpOverlapped, sizeof(OVERLAPPED));
   11.46      res = WSASend(s,
   11.47                    lpWsaBuf,
   11.48                    (DWORD)count,
   11.49 -                  &nwritten,
   11.50 +                  NULL,
   11.51                    0,
   11.52                    lpOverlapped,
   11.53                    NULL);
   11.54 @@ -218,5 +211,5 @@
   11.55          JNU_ThrowIOExceptionWithLastError(env, "WSASend failed");
   11.56          return IOS_THROWN;
   11.57      }
   11.58 -    return (jint)nwritten;
   11.59 +    return IOS_UNAVAILABLE;
   11.60  }
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/test/java/lang/Runtime/shutdown/ShutdownHooks.java	Mon May 04 22:16:02 2009 -0700
    12.3 @@ -0,0 +1,69 @@
    12.4 +/*
    12.5 + * Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    12.7 + *
    12.8 + * This code is free software; you can redistribute it and/or modify it
    12.9 + * under the terms of the GNU General Public License version 2 only, as
   12.10 + * published by the Free Software Foundation.
   12.11 + *
   12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   12.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   12.15 + * version 2 for more details (a copy is included in the LICENSE file that
   12.16 + * accompanied this code).
   12.17 + *
   12.18 + * You should have received a copy of the GNU General Public License version
   12.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   12.21 + *
   12.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   12.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   12.24 + * have any questions.
   12.25 + */
   12.26 +
   12.27 +/*
   12.28 + * @bug      6829503
   12.29 + * @summary  1) Test Console and DeleteOnExitHook can be initialized
   12.30 + *              while shutdown is in progress
   12.31 + *           2) Test if files that are added by the application shutdown
   12.32 + *              hook are deleted on exit during shutdown
   12.33 + */
   12.34 +import java.io.*;
   12.35 +public class ShutdownHooks {
   12.36 +    private static File file;
   12.37 +    public static void main(String[] args) throws Exception {
   12.38 +        if (args.length != 2) {
   12.39 +            throw new IllegalArgumentException("Usage: ShutdownHooks <dir> <filename>");
   12.40 +        }
   12.41 +
   12.42 +        // Add a shutdown hook
   12.43 +        Runtime.getRuntime().addShutdownHook(new Cleaner());
   12.44 +
   12.45 +        File dir = new File(args[0]);
   12.46 +        file = new File(dir, args[1]);
   12.47 +        // write to file
   12.48 +        System.out.println("writing to "+ file);
   12.49 +        PrintWriter pw = new PrintWriter(file);
   12.50 +        pw.println("Shutdown begins");
   12.51 +        pw.close();
   12.52 +    }
   12.53 +
   12.54 +    public static class Cleaner extends Thread {
   12.55 +        public void run() {
   12.56 +            // register the Console's shutdown hook while the application
   12.57 +            // shutdown hook is running
   12.58 +            Console cons = System.console();
   12.59 +            // register the DeleteOnExitHook while the application
   12.60 +            // shutdown hook is running
   12.61 +            file.deleteOnExit();
   12.62 +            try {
   12.63 +                PrintWriter pw = new PrintWriter(file);
   12.64 +                pw.println("file is being deleted");
   12.65 +                pw.close();
   12.66 +            } catch (FileNotFoundException e) {
   12.67 +                throw new RuntimeException(e);
   12.68 +            }
   12.69 +        }
   12.70 +    }
   12.71 +
   12.72 +}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/java/lang/Runtime/shutdown/ShutdownHooks.sh	Mon May 04 22:16:02 2009 -0700
    13.3 @@ -0,0 +1,57 @@
    13.4 +#!/bin/sh
    13.5 +
    13.6 +#
    13.7 +# Copyright 2009 Sun Microsystems, Inc.  All Rights Reserved.
    13.8 +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    13.9 +#
   13.10 +# This code is free software; you can redistribute it and/or modify it
   13.11 +# under the terms of the GNU General Public License version 2 only, as
   13.12 +# published by the Free Software Foundation.
   13.13 +#
   13.14 +# This code is distributed in the hope that it will be useful, but WITHOUT
   13.15 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13.16 +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   13.17 +# version 2 for more details (a copy is included in the LICENSE file that
   13.18 +# accompanied this code).
   13.19 +#
   13.20 +# You should have received a copy of the GNU General Public License version
   13.21 +# 2 along with this work; if not, write to the Free Software Foundation,
   13.22 +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   13.23 +#
   13.24 +# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   13.25 +# CA 95054 USA or visit www.sun.com if you need additional information or
   13.26 +# have any questions.
   13.27 +#
   13.28 +
   13.29 +
   13.30 +# @test
   13.31 +# @bug 6829503
   13.32 +# @summary  1) Test Console and DeleteOnExitHook can be initialized
   13.33 +#              while shutdown is in progress
   13.34 +#           2) Test if files that are added by the application shutdown
   13.35 +#              hook are deleted on exit during shutdown
   13.36 +#
   13.37 +# @build ShutdownHooks 
   13.38 +# @run shell ShutdownHooks.sh
   13.39 +
   13.40 +if [ "${TESTJAVA}" = "" ]
   13.41 +then
   13.42 +  echo "TESTJAVA not set.  Test cannot execute.  Failed."
   13.43 +  exit 1
   13.44 +fi
   13.45 +
   13.46 +FILENAME=fileToBeDeleted
   13.47 +rm -f ${TESTCLASSES}/${FILENAME}
   13.48 +
   13.49 +# create the file to be deleted on exit
   13.50 +echo "testing shutdown" > ${TESTCLASSES}/${FILENAME}
   13.51 +
   13.52 +${TESTJAVA}/bin/java ${TESTVMOPTS} -classpath ${TESTCLASSES} ShutdownHooks ${TESTCLASSES} $FILENAME 
   13.53 +if [ $? != 0 ] ; then
   13.54 +  echo "Test Failed"; exit 1
   13.55 +fi
   13.56 +
   13.57 +if [ -f ${TESTCLASSES}/${FILENAME} ]; then
   13.58 +  echo "Test Failed: ${TESTCLASSES}/${FILENAME} not deleted"; exit 2
   13.59 +fi
   13.60 +echo "ShutdownHooks test passed.";
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/test/java/nio/channels/AsynchronousSocketChannel/StressLoopback.java	Mon May 04 22:16:02 2009 -0700
    14.3 @@ -0,0 +1,183 @@
    14.4 +/*
    14.5 + * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.
   14.11 + *
   14.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.15 + * version 2 for more details (a copy is included in the LICENSE file that
   14.16 + * accompanied this code).
   14.17 + *
   14.18 + * You should have received a copy of the GNU General Public License version
   14.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.21 + *
   14.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   14.23 + * CA 95054 USA or visit www.sun.com if you need additional information or
   14.24 + * have any questions.
   14.25 + */
   14.26 +
   14.27 +/* @test
   14.28 + * @bug 6834246
   14.29 + * @summary Stress test connections through the loopback interface
   14.30 + */
   14.31 +
   14.32 +import java.nio.ByteBuffer;
   14.33 +import java.net.*;
   14.34 +import java.nio.channels.*;
   14.35 +import java.util.Random;
   14.36 +import java.io.IOException;
   14.37 +
   14.38 +public class StressLoopback {
   14.39 +    static final Random rand = new Random();
   14.40 +
   14.41 +    public static void main(String[] args) throws Exception {
   14.42 +        // setup listener
   14.43 +        AsynchronousServerSocketChannel listener =
   14.44 +            AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(0));
   14.45 +        int port =((InetSocketAddress)(listener.getLocalAddress())).getPort();
   14.46 +        InetAddress lh = InetAddress.getLocalHost();
   14.47 +        SocketAddress remote = new InetSocketAddress(lh, port);
   14.48 +
   14.49 +        // create sources and sinks
   14.50 +        int count = 2 + rand.nextInt(9);
   14.51 +        Source[] source = new Source[count];
   14.52 +        Sink[] sink = new Sink[count];
   14.53 +        for (int i=0; i<count; i++) {
   14.54 +            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
   14.55 +            ch.connect(remote).get();
   14.56 +            source[i] = new Source(ch);
   14.57 +            sink[i] = new Sink(listener.accept().get());
   14.58 +        }
   14.59 +
   14.60 +        // start the sinks and sources
   14.61 +        for (int i=0; i<count; i++) {
   14.62 +            sink[i].start();
   14.63 +            source[i].start();
   14.64 +        }
   14.65 +
   14.66 +        // let the test run for a while
   14.67 +        Thread.sleep(20*1000);
   14.68 +
   14.69 +        // wait until everyone is done
   14.70 +        boolean failed = false;
   14.71 +        long total = 0L;
   14.72 +        for (int i=0; i<count; i++) {
   14.73 +            long nwrote = source[i].finish();
   14.74 +            long nread = sink[i].finish();
   14.75 +            if (nread != nwrote)
   14.76 +                failed = true;
   14.77 +            System.out.format("%d -> %d (%s)\n",
   14.78 +                nwrote, nread, (failed) ? "FAIL" : "PASS");
   14.79 +            total += nwrote;
   14.80 +        }
   14.81 +        if (failed)
   14.82 +            throw new RuntimeException("Test failed - see log for details");
   14.83 +        System.out.format("Total sent %d MB\n", total / (1024L * 1024L));
   14.84 +    }
   14.85 +
   14.86 +    /**
   14.87 +     * Writes bytes to a channel until "done". When done the channel is closed.
   14.88 +     */
   14.89 +    static class Source {
   14.90 +        private final AsynchronousByteChannel channel;
   14.91 +        private final ByteBuffer sentBuffer;
   14.92 +        private volatile long bytesSent;
   14.93 +        private volatile boolean finished;
   14.94 +
   14.95 +        Source(AsynchronousByteChannel channel) {
   14.96 +            this.channel = channel;
   14.97 +            int size = 1024 + rand.nextInt(10000);
   14.98 +            this.sentBuffer = (rand.nextBoolean()) ?
   14.99 +                ByteBuffer.allocateDirect(size) : ByteBuffer.allocate(size);
  14.100 +        }
  14.101 +
  14.102 +        void start() {
  14.103 +            sentBuffer.position(0);
  14.104 +            sentBuffer.limit(sentBuffer.capacity());
  14.105 +            channel.write(sentBuffer, null, new CompletionHandler<Integer,Void> () {
  14.106 +                public void completed(Integer nwrote, Void att) {
  14.107 +                    bytesSent += nwrote;
  14.108 +                    if (finished) {
  14.109 +                        closeUnchecked(channel);
  14.110 +                    } else {
  14.111 +                        sentBuffer.position(0);
  14.112 +                        sentBuffer.limit(sentBuffer.capacity());
  14.113 +                        channel.write(sentBuffer, null, this);
  14.114 +                    }
  14.115 +                }
  14.116 +                public void failed(Throwable exc, Void att) {
  14.117 +                    exc.printStackTrace();
  14.118 +                    closeUnchecked(channel);
  14.119 +                }
  14.120 +                public void cancelled(Void att) {
  14.121 +                }
  14.122 +            });
  14.123 +        }
  14.124 +
  14.125 +        long finish() {
  14.126 +            finished = true;
  14.127 +            waitUntilClosed(channel);
  14.128 +            return bytesSent;
  14.129 +        }
  14.130 +    }
  14.131 +
  14.132 +    /**
  14.133 +     * Read bytes from a channel until EOF is received.
  14.134 +     */
  14.135 +    static class Sink {
  14.136 +        private final AsynchronousByteChannel channel;
  14.137 +        private final ByteBuffer readBuffer;
  14.138 +        private volatile long bytesRead;
  14.139 +
  14.140 +        Sink(AsynchronousByteChannel channel) {
  14.141 +            this.channel = channel;
  14.142 +            int size = 1024 + rand.nextInt(10000);
  14.143 +            this.readBuffer = (rand.nextBoolean()) ?
  14.144 +                ByteBuffer.allocateDirect(size) : ByteBuffer.allocate(size);
  14.145 +        }
  14.146 +
  14.147 +        void start() {
  14.148 +            channel.read(readBuffer, null, new CompletionHandler<Integer,Void> () {
  14.149 +                public void completed(Integer nread, Void att) {
  14.150 +                    if (nread < 0) {
  14.151 +                        closeUnchecked(channel);
  14.152 +                    } else {
  14.153 +                        bytesRead += nread;
  14.154 +                        readBuffer.clear();
  14.155 +                        channel.read(readBuffer, null, this);
  14.156 +                    }
  14.157 +                }
  14.158 +                public void failed(Throwable exc, Void att) {
  14.159 +                    exc.printStackTrace();
  14.160 +                    closeUnchecked(channel);
  14.161 +                }
  14.162 +                public void cancelled(Void att) {
  14.163 +                }
  14.164 +            });
  14.165 +        }
  14.166 +
  14.167 +        long finish() {
  14.168 +            waitUntilClosed(channel);
  14.169 +            return bytesRead;
  14.170 +        }
  14.171 +    }
  14.172 +
  14.173 +    static void waitUntilClosed(Channel c) {
  14.174 +        while (c.isOpen()) {
  14.175 +            try {
  14.176 +                Thread.sleep(100);
  14.177 +            } catch (InterruptedException ignore) { }
  14.178 +        }
  14.179 +    }
  14.180 +
  14.181 +    static void closeUnchecked(Channel c) {
  14.182 +        try {
  14.183 +            c.close();
  14.184 +        } catch (IOException ignore) { }
  14.185 +    }
  14.186 +}