Explicit thread group on DefaultThreadFactory.
Motivation: Fixes #5084. We (gRPC) encountered a bug that was triggered by grpc/grpc-java@d927180. After that commit, event loop threads are created per task by NioEventLoopGroup, and inherits the thread group of the caller, which in our case is an application-provided request-scope thread. Things go south when the application tries to manipulate (e.g., interrupt and join) all threads of the request-scope thread group, which unexpectedly include the event loop threads. Modifications: DefaultThreadFactory will save the current thread group in constructor, and apply it to all new threads. Result: Threads created by DefaultThreadFactory will be in the same thread group as the thread where the factory is created.
This commit is contained in:
parent
66ce014074
commit
8bdf73edea
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package io.netty.util.concurrent;
|
package io.netty.util.concurrent;
|
||||||
|
|
||||||
|
import io.netty.util.internal.ObjectUtil;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@ -33,6 +34,7 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||||||
private final String prefix;
|
private final String prefix;
|
||||||
private final boolean daemon;
|
private final boolean daemon;
|
||||||
private final int priority;
|
private final int priority;
|
||||||
|
private final ThreadGroup threadGroup;
|
||||||
|
|
||||||
public DefaultThreadFactory(Class<?> poolType) {
|
public DefaultThreadFactory(Class<?> poolType) {
|
||||||
this(poolType, false, Thread.NORM_PRIORITY);
|
this(poolType, false, Thread.NORM_PRIORITY);
|
||||||
@ -82,7 +84,7 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
|
public DefaultThreadFactory(String poolName, boolean daemon, int priority, ThreadGroup threadGroup) {
|
||||||
if (poolName == null) {
|
if (poolName == null) {
|
||||||
throw new NullPointerException("poolName");
|
throw new NullPointerException("poolName");
|
||||||
}
|
}
|
||||||
@ -94,6 +96,11 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||||||
prefix = poolName + '-' + poolId.incrementAndGet() + '-';
|
prefix = poolName + '-' + poolId.incrementAndGet() + '-';
|
||||||
this.daemon = daemon;
|
this.daemon = daemon;
|
||||||
this.priority = priority;
|
this.priority = priority;
|
||||||
|
this.threadGroup = ObjectUtil.checkNotNull(threadGroup, "threadGroup");
|
||||||
|
}
|
||||||
|
|
||||||
|
public DefaultThreadFactory(String poolName, boolean daemon, int priority) {
|
||||||
|
this(poolName, daemon, priority, Thread.currentThread().getThreadGroup());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -119,8 +126,9 @@ public class DefaultThreadFactory implements ThreadFactory {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Once we can break the API we should add ThreadGroup to the arguments of this method.
|
||||||
protected Thread newThread(Runnable r, String name) {
|
protected Thread newThread(Runnable r, String name) {
|
||||||
return new FastThreadLocalThread(r, name);
|
return new FastThreadLocalThread(threadGroup, r, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class DefaultRunnableDecorator implements Runnable {
|
private static final class DefaultRunnableDecorator implements Runnable {
|
||||||
|
Loading…
Reference in New Issue
Block a user