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