6810254: Lazily instantiate the shared secret access objects
Register the shutdown hooks only when needed and remove JavaIODeleteOnExitAccess Reviewed-by: alanb
This commit is contained in:
parent
d3a7a9549d
commit
0a64902056
@ -449,7 +449,6 @@ JAVA_JAVA_java = \
|
|||||||
sun/misc/Service.java \
|
sun/misc/Service.java \
|
||||||
sun/misc/JavaLangAccess.java \
|
sun/misc/JavaLangAccess.java \
|
||||||
sun/misc/JavaIOAccess.java \
|
sun/misc/JavaIOAccess.java \
|
||||||
sun/misc/JavaIODeleteOnExitAccess.java \
|
|
||||||
sun/misc/JavaIOFileDescriptorAccess.java \
|
sun/misc/JavaIOFileDescriptorAccess.java \
|
||||||
sun/misc/JavaNioAccess.java
|
sun/misc/JavaNioAccess.java
|
||||||
|
|
||||||
|
@ -503,6 +503,21 @@ public final class Console implements Flushable
|
|||||||
|
|
||||||
// Set up JavaIOAccess in SharedSecrets
|
// Set up JavaIOAccess in SharedSecrets
|
||||||
static {
|
static {
|
||||||
|
|
||||||
|
// Add a shutdown hook to restore console's echo state should
|
||||||
|
// it be necessary.
|
||||||
|
sun.misc.SharedSecrets.getJavaLangAccess()
|
||||||
|
.registerShutdownHook(0 /* shutdown hook invocation order */,
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
if (echoOff) {
|
||||||
|
echo(true);
|
||||||
|
}
|
||||||
|
} catch (IOException x) { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
|
sun.misc.SharedSecrets.setJavaIOAccess(new sun.misc.JavaIOAccess() {
|
||||||
public Console console() {
|
public Console console() {
|
||||||
if (istty()) {
|
if (istty()) {
|
||||||
@ -513,20 +528,6 @@ public final class Console implements Flushable
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a shutdown hook to restore console's echo state should
|
|
||||||
// it be necessary.
|
|
||||||
public Runnable consoleRestoreHook() {
|
|
||||||
return new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
if (echoOff) {
|
|
||||||
echo(true);
|
|
||||||
}
|
|
||||||
} catch (IOException x) {}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public Charset charset() {
|
public Charset charset() {
|
||||||
// This method is called in sun.security.util.Password,
|
// This method is called in sun.security.util.Password,
|
||||||
// cons already exists when this method is called
|
// cons already exists when this method is called
|
||||||
|
@ -34,17 +34,18 @@ import java.io.File;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class DeleteOnExitHook {
|
class DeleteOnExitHook {
|
||||||
private static DeleteOnExitHook instance = null;
|
static {
|
||||||
|
sun.misc.SharedSecrets.getJavaLangAccess()
|
||||||
|
.registerShutdownHook(2 /* Shutdown hook invocation order */,
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
runHooks();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static LinkedHashSet<String> files = new LinkedHashSet<String>();
|
private static LinkedHashSet<String> files = new LinkedHashSet<String>();
|
||||||
|
|
||||||
static DeleteOnExitHook hook() {
|
|
||||||
if (instance == null)
|
|
||||||
instance = new DeleteOnExitHook();
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private DeleteOnExitHook() {}
|
private DeleteOnExitHook() {}
|
||||||
|
|
||||||
static synchronized void add(String file) {
|
static synchronized void add(String file) {
|
||||||
@ -54,7 +55,7 @@ class DeleteOnExitHook {
|
|||||||
files.add(file);
|
files.add(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() {
|
static void runHooks() {
|
||||||
LinkedHashSet<String> theFiles;
|
LinkedHashSet<String> theFiles;
|
||||||
|
|
||||||
synchronized (DeleteOnExitHook.class) {
|
synchronized (DeleteOnExitHook.class) {
|
||||||
|
@ -2147,18 +2147,6 @@ public class File
|
|||||||
/** use serialVersionUID from JDK 1.0.2 for interoperability */
|
/** use serialVersionUID from JDK 1.0.2 for interoperability */
|
||||||
private static final long serialVersionUID = 301077366599181567L;
|
private static final long serialVersionUID = 301077366599181567L;
|
||||||
|
|
||||||
// Set up JavaIODeleteOnExitAccess in SharedSecrets
|
|
||||||
// Added here as DeleteOnExitHook is package-private and SharedSecrets cannot easily access it.
|
|
||||||
static {
|
|
||||||
sun.misc.SharedSecrets.setJavaIODeleteOnExitAccess(
|
|
||||||
new sun.misc.JavaIODeleteOnExitAccess() {
|
|
||||||
public void run() {
|
|
||||||
DeleteOnExitHook.hook().run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- Integration with java.nio.file --
|
// -- Integration with java.nio.file --
|
||||||
|
|
||||||
private volatile transient Path filePath;
|
private volatile transient Path filePath;
|
||||||
|
@ -34,19 +34,19 @@ import java.util.*;
|
|||||||
* @see java.lang.Runtime#removeShutdownHook
|
* @see java.lang.Runtime#removeShutdownHook
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class ApplicationShutdownHooks implements Runnable {
|
class ApplicationShutdownHooks {
|
||||||
private static ApplicationShutdownHooks instance = null;
|
static {
|
||||||
|
Shutdown.add(1 /* shutdown hook invocation order */,
|
||||||
|
new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
runHooks();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* The set of registered hooks */
|
/* The set of registered hooks */
|
||||||
private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
|
private static IdentityHashMap<Thread, Thread> hooks = new IdentityHashMap<Thread, Thread>();
|
||||||
|
|
||||||
static synchronized ApplicationShutdownHooks hook() {
|
|
||||||
if (instance == null)
|
|
||||||
instance = new ApplicationShutdownHooks();
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ApplicationShutdownHooks() {}
|
private ApplicationShutdownHooks() {}
|
||||||
|
|
||||||
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
|
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
|
||||||
@ -82,7 +82,7 @@ class ApplicationShutdownHooks implements Runnable {
|
|||||||
* to run in. Hooks are run concurrently and this method waits for
|
* to run in. Hooks are run concurrently and this method waits for
|
||||||
* them to finish.
|
* them to finish.
|
||||||
*/
|
*/
|
||||||
public void run() {
|
static void runHooks() {
|
||||||
Collection<Thread> threads;
|
Collection<Thread> threads;
|
||||||
synchronized(ApplicationShutdownHooks.class) {
|
synchronized(ApplicationShutdownHooks.class) {
|
||||||
threads = hooks.keySet();
|
threads = hooks.keySet();
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
|
|
||||||
package java.lang;
|
package java.lang;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Package-private utility class containing data structures and logic
|
* Package-private utility class containing data structures and logic
|
||||||
@ -47,8 +45,13 @@ class Shutdown {
|
|||||||
/* Should we run all finalizers upon exit? */
|
/* Should we run all finalizers upon exit? */
|
||||||
private static boolean runFinalizersOnExit = false;
|
private static boolean runFinalizersOnExit = false;
|
||||||
|
|
||||||
/* The set of registered, wrapped hooks, or null if there aren't any */
|
// The system shutdown hooks are registered with a predefined slot.
|
||||||
private static ArrayList<Runnable> hooks = new ArrayList<Runnable>();
|
// The list of shutdown hooks is as follows:
|
||||||
|
// (0) Console restore hook
|
||||||
|
// (1) Application hooks
|
||||||
|
// (2) DeleteOnExit hook
|
||||||
|
private static final int MAX_SYSTEM_HOOKS = 10;
|
||||||
|
private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
|
||||||
|
|
||||||
/* The preceding static fields are protected by this lock */
|
/* The preceding static fields are protected by this lock */
|
||||||
private static class Lock { };
|
private static class Lock { };
|
||||||
@ -68,33 +71,18 @@ class Shutdown {
|
|||||||
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
|
/* Add a new shutdown hook. Checks the shutdown state and the hook itself,
|
||||||
* but does not do any security checks.
|
* but does not do any security checks.
|
||||||
*/
|
*/
|
||||||
static void add(Runnable hook) {
|
static void add(int slot, Runnable hook) {
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
if (state > RUNNING)
|
if (state > RUNNING)
|
||||||
throw new IllegalStateException("Shutdown in progress");
|
throw new IllegalStateException("Shutdown in progress");
|
||||||
|
|
||||||
hooks.add(hook);
|
if (hooks[slot] != null)
|
||||||
|
throw new InternalError("Shutdown hook at slot " + slot + " already registered");
|
||||||
|
|
||||||
|
hooks[slot] = hook;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Remove a previously-registered hook. Like the add method, this method
|
|
||||||
* does not do any security checks.
|
|
||||||
*/
|
|
||||||
static boolean remove(Runnable hook) {
|
|
||||||
synchronized (lock) {
|
|
||||||
if (state > RUNNING)
|
|
||||||
throw new IllegalStateException("Shutdown in progress");
|
|
||||||
if (hook == null) throw new NullPointerException();
|
|
||||||
if (hooks == null) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
return hooks.remove(hook);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Run all registered shutdown hooks
|
/* Run all registered shutdown hooks
|
||||||
*/
|
*/
|
||||||
private static void runHooks() {
|
private static void runHooks() {
|
||||||
@ -103,7 +91,7 @@ class Shutdown {
|
|||||||
*/
|
*/
|
||||||
for (Runnable hook : hooks) {
|
for (Runnable hook : hooks) {
|
||||||
try {
|
try {
|
||||||
hook.run();
|
if (hook != null) hook.run();
|
||||||
} catch(Throwable t) {
|
} catch(Throwable t) {
|
||||||
if (t instanceof ThreadDeath) {
|
if (t instanceof ThreadDeath) {
|
||||||
ThreadDeath td = (ThreadDeath)t;
|
ThreadDeath td = (ThreadDeath)t;
|
||||||
|
@ -1121,14 +1121,6 @@ public final class System {
|
|||||||
// Setup Java signal handlers for HUP, TERM, and INT (where available).
|
// Setup Java signal handlers for HUP, TERM, and INT (where available).
|
||||||
Terminator.setup();
|
Terminator.setup();
|
||||||
|
|
||||||
// The order in with the hooks are added here is important as it
|
|
||||||
// determines the order in which they are run.
|
|
||||||
// (1)Console restore hook needs to be called first.
|
|
||||||
// (2)Application hooks must be run before calling deleteOnExitHook.
|
|
||||||
Shutdown.add(sun.misc.SharedSecrets.getJavaIOAccess().consoleRestoreHook());
|
|
||||||
Shutdown.add(ApplicationShutdownHooks.hook());
|
|
||||||
Shutdown.add(sun.misc.SharedSecrets.getJavaIODeleteOnExitAccess());
|
|
||||||
|
|
||||||
// Initialize any miscellenous operating system settings that need to be
|
// Initialize any miscellenous operating system settings that need to be
|
||||||
// set for the class libraries. Currently this is no-op everywhere except
|
// set for the class libraries. Currently this is no-op everywhere except
|
||||||
// for Windows where the process-wide error mode is set before the java.io
|
// for Windows where the process-wide error mode is set before the java.io
|
||||||
@ -1174,6 +1166,9 @@ public final class System {
|
|||||||
public void blockedOn(Thread t, Interruptible b) {
|
public void blockedOn(Thread t, Interruptible b) {
|
||||||
t.blockedOn(b);
|
t.blockedOn(b);
|
||||||
}
|
}
|
||||||
|
public void registerShutdownHook(int slot, Runnable r) {
|
||||||
|
Shutdown.add(slot, r);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,5 @@ import java.nio.charset.Charset;
|
|||||||
|
|
||||||
public interface JavaIOAccess {
|
public interface JavaIOAccess {
|
||||||
public Console console();
|
public Console console();
|
||||||
public Runnable consoleRestoreHook();
|
|
||||||
public Charset charset();
|
public Charset charset();
|
||||||
}
|
}
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2005 Sun Microsystems, Inc. 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. Sun designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Sun in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
||||||
* version 2 for more details (a copy is included in the LICENSE file that
|
|
||||||
* accompanied this code).
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License version
|
|
||||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
||||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
||||||
*
|
|
||||||
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
||||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
|
||||||
* have any questions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package sun.misc;
|
|
||||||
|
|
||||||
public interface JavaIODeleteOnExitAccess extends Runnable {
|
|
||||||
public void run();
|
|
||||||
}
|
|
@ -54,4 +54,7 @@ public interface JavaLangAccess {
|
|||||||
|
|
||||||
/** Set thread's blocker field. */
|
/** Set thread's blocker field. */
|
||||||
void blockedOn(Thread t, Interruptible b);
|
void blockedOn(Thread t, Interruptible b);
|
||||||
|
|
||||||
|
/** register shutdown hook */
|
||||||
|
void registerShutdownHook(int slot, Runnable r);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,6 @@ public class SharedSecrets {
|
|||||||
private static JavaUtilJarAccess javaUtilJarAccess;
|
private static JavaUtilJarAccess javaUtilJarAccess;
|
||||||
private static JavaLangAccess javaLangAccess;
|
private static JavaLangAccess javaLangAccess;
|
||||||
private static JavaIOAccess javaIOAccess;
|
private static JavaIOAccess javaIOAccess;
|
||||||
private static JavaIODeleteOnExitAccess javaIODeleteOnExitAccess;
|
|
||||||
private static JavaNetAccess javaNetAccess;
|
private static JavaNetAccess javaNetAccess;
|
||||||
private static JavaNioAccess javaNioAccess;
|
private static JavaNioAccess javaNioAccess;
|
||||||
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
|
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
|
||||||
@ -103,17 +102,6 @@ public class SharedSecrets {
|
|||||||
return javaIOAccess;
|
return javaIOAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setJavaIODeleteOnExitAccess(JavaIODeleteOnExitAccess jida) {
|
|
||||||
javaIODeleteOnExitAccess = jida;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static JavaIODeleteOnExitAccess getJavaIODeleteOnExitAccess() {
|
|
||||||
if (javaIODeleteOnExitAccess == null) {
|
|
||||||
unsafe.ensureClassInitialized(File.class);
|
|
||||||
}
|
|
||||||
return javaIODeleteOnExitAccess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
|
public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) {
|
||||||
javaIOFileDescriptorAccess = jiofda;
|
javaIOFileDescriptorAccess = jiofda;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user