8151571: InnocuousThread cannot be created during early startup
Reviewed-by: alanb, plevart, chegar
This commit is contained in:
parent
da3998f139
commit
264639c70b
jdk/src/java.base/share/classes
jdk/internal
sun
@ -135,7 +135,7 @@ public final class BootstrapLogger implements Logger, PlatformLogger.Bridge,
|
||||
Thread thread = AccessController.doPrivileged(new PrivilegedAction<Thread>() {
|
||||
@Override
|
||||
public Thread run() {
|
||||
Thread t = new InnocuousThread(new BootstrapMessageLoggerTask(owner, r));
|
||||
Thread t = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r));
|
||||
t.setName("BootstrapMessageLoggerTask-"+t.getName());
|
||||
return t;
|
||||
}
|
||||
|
@ -45,20 +45,49 @@ public final class InnocuousThread extends Thread {
|
||||
private static final long CONTEXTCLASSLOADER;
|
||||
|
||||
private static final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
|
||||
public InnocuousThread(Runnable target) {
|
||||
this(INNOCUOUSTHREADGROUP, target,
|
||||
"InnocuousThread-" + threadNumber.getAndIncrement());
|
||||
private static String newName() {
|
||||
return "InnocuousThread-" + threadNumber.getAndIncrement();
|
||||
}
|
||||
|
||||
public InnocuousThread(Runnable target, String name) {
|
||||
this(INNOCUOUSTHREADGROUP, target, name);
|
||||
/**
|
||||
* Returns a new InnocuousThread with an auto-generated thread name
|
||||
* and its context class loader is set to the system class loader.
|
||||
*/
|
||||
public static Thread newThread(Runnable target) {
|
||||
return newThread(newName(), target);
|
||||
}
|
||||
|
||||
public InnocuousThread(ThreadGroup group, Runnable target, String name) {
|
||||
/**
|
||||
* Returns a new InnocuousThread with its context class loader
|
||||
* set to the system class loader.
|
||||
*/
|
||||
public static Thread newThread(String name, Runnable target) {
|
||||
return new InnocuousThread(INNOCUOUSTHREADGROUP,
|
||||
target,
|
||||
name,
|
||||
ClassLoader.getSystemClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new InnocuousThread with an auto-generated thread name.
|
||||
* Its context class loader is set to null.
|
||||
*/
|
||||
public static Thread newSystemThread(Runnable target) {
|
||||
return newSystemThread(newName(), target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new InnocuousThread with null context class loader.
|
||||
*/
|
||||
public static Thread newSystemThread(String name, Runnable target) {
|
||||
return new InnocuousThread(INNOCUOUSTHREADGROUP,
|
||||
target, name, null);
|
||||
}
|
||||
|
||||
private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) {
|
||||
super(group, target, name, 0L, false);
|
||||
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
|
||||
UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, ClassLoader.getSystemClassLoader());
|
||||
UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,24 +25,44 @@
|
||||
|
||||
package jdk.internal.ref;
|
||||
|
||||
import jdk.internal.misc.InnocuousThread;
|
||||
|
||||
import java.lang.ref.Cleaner;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* CleanerFactory provides a Cleaner for use within OpenJDK modules.
|
||||
* CleanerFactory provides a Cleaner for use within system modules.
|
||||
* The cleaner is created on the first reference to the CleanerFactory.
|
||||
*/
|
||||
public final class CleanerFactory {
|
||||
|
||||
/* The common Cleaner. */
|
||||
private final static Cleaner commonCleaner = Cleaner.create();
|
||||
private final static Cleaner commonCleaner = Cleaner.create(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
@Override
|
||||
public Thread run() {
|
||||
Thread t = InnocuousThread.newSystemThread("Common-Cleaner", r);
|
||||
t.setPriority(Thread.MAX_PRIORITY - 2);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Cleaner for use within OpenJDK modules.
|
||||
* Cleaner for use within system modules.
|
||||
*
|
||||
* @return a Cleaner for use within OpenJDK modules
|
||||
* This Cleaner will run on a thread whose context class loader
|
||||
* is {@code null}. The system cleaning action to perform in
|
||||
* this Cleaner should handle a {@code null} context class loader.
|
||||
*
|
||||
* @return a Cleaner for use within system modules
|
||||
*/
|
||||
public static Cleaner cleaner() {
|
||||
return commonCleaner;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -324,10 +324,10 @@ public final class CleanerImpl implements Runnable {
|
||||
final AtomicInteger cleanerThreadNumber = new AtomicInteger();
|
||||
|
||||
public Thread newThread(Runnable r) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<Thread>() {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<>() {
|
||||
@Override
|
||||
public Thread run() {
|
||||
Thread t = new InnocuousThread(r);
|
||||
Thread t = InnocuousThread.newThread(r);
|
||||
t.setPriority(Thread.MAX_PRIORITY - 2);
|
||||
t.setName("Cleaner-" + cleanerThreadNumber.getAndIncrement());
|
||||
return t;
|
||||
|
@ -96,12 +96,9 @@ public class KeepAliveCache
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<>() {
|
||||
public Void run() {
|
||||
keepAliveTimer = new InnocuousThread(cache, "Keep-Alive-Timer");
|
||||
keepAliveTimer = InnocuousThread.newSystemThread("Keep-Alive-Timer", cache);
|
||||
keepAliveTimer.setDaemon(true);
|
||||
keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2);
|
||||
// Set the context class loader to null in order to avoid
|
||||
// keeping a strong reference to an application classloader.
|
||||
keepAliveTimer.setContextClassLoader(null);
|
||||
keepAliveTimer.start();
|
||||
return null;
|
||||
}
|
||||
|
@ -173,12 +173,9 @@ class KeepAliveStream extends MeteredStream implements Hurryable {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
cleanerThread = new InnocuousThread(queue, "Keep-Alive-SocketCleaner");
|
||||
cleanerThread = InnocuousThread.newSystemThread("Keep-Alive-SocketCleaner", queue);
|
||||
cleanerThread.setDaemon(true);
|
||||
cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
|
||||
// Set the context class loader to null in order to avoid
|
||||
// keeping a strong reference to an application classloader.
|
||||
cleanerThread.setContextClassLoader(null);
|
||||
cleanerThread.start();
|
||||
return null;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ public class ThreadPool {
|
||||
} else {
|
||||
return (Runnable r) -> {
|
||||
PrivilegedAction<Thread> action = () -> {
|
||||
Thread t = new InnocuousThread(r);
|
||||
Thread t = InnocuousThread.newThread(r);
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
};
|
||||
|
@ -25,8 +25,9 @@
|
||||
|
||||
package sun.nio.fs;
|
||||
|
||||
import java.lang.ref.Cleaner.Cleanable;
|
||||
import jdk.internal.misc.Unsafe;
|
||||
import jdk.internal.ref.Cleaner;
|
||||
import jdk.internal.ref.CleanerFactory;
|
||||
|
||||
/**
|
||||
* A light-weight buffer in native memory.
|
||||
@ -37,7 +38,7 @@ class NativeBuffer {
|
||||
|
||||
private final long address;
|
||||
private final int size;
|
||||
private final Cleaner cleaner;
|
||||
private final Cleanable cleanable;
|
||||
|
||||
// optional "owner" to avoid copying
|
||||
// (only safe for use by thread-local caches)
|
||||
@ -56,7 +57,8 @@ class NativeBuffer {
|
||||
NativeBuffer(int size) {
|
||||
this.address = unsafe.allocateMemory(size);
|
||||
this.size = size;
|
||||
this.cleaner = Cleaner.create(this, new Deallocator(address));
|
||||
this.cleanable = CleanerFactory.cleaner()
|
||||
.register(this, new Deallocator(address));
|
||||
}
|
||||
|
||||
void release() {
|
||||
@ -72,7 +74,7 @@ class NativeBuffer {
|
||||
}
|
||||
|
||||
void free() {
|
||||
cleaner.clean();
|
||||
cleanable.clean();
|
||||
}
|
||||
|
||||
// not synchronized; only safe for use by thread-local caches
|
||||
|
Loading…
x
Reference in New Issue
Block a user