提交 0a3a2c67 编写于 作者: R robm

8156824: com.sun.jndi.ldap.pool.PoolCleaner should clear its context class loader

Reviewed-by: chegar
上级 fd2d43a5
......@@ -39,6 +39,7 @@ import java.security.PrivilegedAction;
import com.sun.jndi.ldap.pool.PoolCleaner;
import com.sun.jndi.ldap.pool.Pool;
import sun.misc.InnocuousThread;
/**
* Contains utilities for managing connection pools of LdapClient.
......@@ -163,7 +164,17 @@ public final class LdapPoolManager {
if (idleTimeout > 0) {
// Create cleaner to expire idle connections
new PoolCleaner(idleTimeout, pools).start();
PrivilegedAction<Void> pa = new PrivilegedAction<Void>() {
public Void run() {
Thread t = InnocuousThread.newSystemThread(
"LDAP PoolCleaner",
new PoolCleaner(idleTimeout, pools));
assert t.getContextClassLoader() == null;
t.setDaemon(true);
t.start();
return null;
}};
AccessController.doPrivileged(pa);
}
if (debug) {
......
......@@ -30,7 +30,7 @@ package com.sun.jndi.ldap.pool;
*
* @author Rosanna Lee
*/
final public class PoolCleaner extends Thread {
final public class PoolCleaner implements Runnable {
final private Pool[] pools;
final private long period;
......@@ -42,9 +42,9 @@ final public class PoolCleaner extends Thread {
super();
this.period = period;
this.pools = pools.clone();
setDaemon(true);
}
@Override
public void run() {
long threshold;
while (true) {
......
......@@ -26,7 +26,10 @@
package sun.misc;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.ProtectionDomain;
import java.security.PrivilegedAction;
import java.util.concurrent.atomic.AtomicInteger;
/**
* A thread that has no permissions, is not a member of any user-defined
......@@ -36,15 +39,44 @@ import java.security.ProtectionDomain;
*/
public final class InnocuousThread extends Thread {
private static final Unsafe UNSAFE;
private static final ThreadGroup THREADGROUP;
private static final long THREAD_LOCALS;
private static final long INHERITABLE_THREAD_LOCALS;
private static final ThreadGroup INNOCUOUSTHREADGROUP;
private static final AccessControlContext ACC;
private static final long THREADLOCALS;
private static final long INHERITABLETHREADLOCALS;
private static final long INHERITEDACCESSCONTROLCONTEXT;
private static final long CONTEXTCLASSLOADER;
private static final AtomicInteger threadNumber = new AtomicInteger(1);
private static String newName() {
return "InnocuousThread-" + threadNumber.getAndIncrement();
}
/**
* 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);
}
public InnocuousThread(Runnable target) {
super(THREADGROUP, target, "anInnocuousThread");
super(INNOCUOUSTHREADGROUP, target, newName());
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
eraseThreadLocals();
}
private InnocuousThread(ThreadGroup group, Runnable target, String name, ClassLoader tccl) {
super(group, target, name, 0L);
UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC);
UNSAFE.putOrderedObject(this, CONTEXTCLASSLOADER, tccl);
eraseThreadLocals();
}
......@@ -79,8 +111,8 @@ public final class InnocuousThread extends Thread {
* Drops all thread locals (and inherited thread locals).
*/
public void eraseThreadLocals() {
UNSAFE.putObject(this, THREADLOCALS, null);
UNSAFE.putObject(this, INHERITABLETHREADLOCALS, null);
UNSAFE.putObject(this, THREAD_LOCALS, null);
UNSAFE.putObject(this, INHERITABLE_THREAD_LOCALS, null);
}
// Use Unsafe to access Thread group and ThreadGroup parent fields
......@@ -95,12 +127,14 @@ public final class InnocuousThread extends Thread {
Class<?> tk = Thread.class;
Class<?> gk = ThreadGroup.class;
THREADLOCALS = UNSAFE.objectFieldOffset
THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("threadLocals"));
INHERITABLETHREADLOCALS = UNSAFE.objectFieldOffset
INHERITABLE_THREAD_LOCALS = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritableThreadLocals"));
INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset
(tk.getDeclaredField("inheritedAccessControlContext"));
CONTEXTCLASSLOADER = UNSAFE.objectFieldOffset
(tk.getDeclaredField("contextClassLoader"));
long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group"));
long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent"));
......@@ -113,7 +147,14 @@ public final class InnocuousThread extends Thread {
break;
group = parent;
}
THREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup");
final ThreadGroup root = group;
INNOCUOUSTHREADGROUP = AccessController.doPrivileged(
new PrivilegedAction<ThreadGroup>() {
@Override
public ThreadGroup run() {
return new ThreadGroup(root, "InnocuousThreadGroup");
}
});
} catch (Exception e) {
throw new Error(e);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册