Code cleanup for shutdown and checking if a thread is in a netty event

loop
This commit is contained in:
nathan 2018-01-14 22:57:18 +01:00
parent 404e54bff8
commit 1d3cd06130

View File

@ -2,7 +2,6 @@ package dorkbox.network.connection;
import java.security.AccessControlException; import java.security.AccessControlException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
@ -188,6 +187,25 @@ class EndPoint {
return true; return true;
} }
/**
* Check to see if the current thread is running from it's OWN thread, or from Netty... This is used to prevent deadlocks.
*
* @return true if the specified thread is as Netty thread, false if it's own thread.
*/
protected
boolean isInEventLoop(Thread thread) {
for (EventLoopGroup loopGroup : eventLoopGroups) {
for (EventExecutor next : loopGroup) {
if (next.inEventLoop(thread)) {
return true;
}
}
}
return false;
}
/** /**
* Safely closes all associated resources/threads/connections. * Safely closes all associated resources/threads/connections.
* <p/> * <p/>
@ -207,44 +225,24 @@ class EndPoint {
// This occurs when calling stop from within a listener callback. // This occurs when calling stop from within a listener callback.
Thread currentThread = Thread.currentThread(); Thread currentThread = Thread.currentThread();
String threadName = currentThread.getName(); String threadName = currentThread.getName();
boolean inShutdownThread = !threadName.equals(shutdownHookName) && !threadName.equals(stopTreadName); boolean isShutdownThread = !threadName.equals(shutdownHookName) && !threadName.equals(stopTreadName);
// used to check the event groups to see if we are running from one of them. NOW we force to // used to check the event groups to see if we are running from one of them. NOW we force to
// ALWAYS shutdown inside a NEW thread // ALWAYS shutdown inside a NEW thread
if (!isShutdownThread || !isInEventLoop(currentThread)) {
if (!inShutdownThread) {
stopInThread(); stopInThread();
} }
else { else {
// we have to make sure always run this from within it's OWN thread -- because if it's run from within Thread thread = new Thread(new Runnable() {
// a client/server thread executor, it will deadlock while waiting for the threadpool to terminate. @Override
boolean isInEventLoop = false; public
for (EventLoopGroup loopGroup : eventLoopGroups) { void run() {
Iterator<EventExecutor> iterator = loopGroup.iterator(); EndPoint.this.stopInThread();
while (iterator.hasNext()) {
EventExecutor next = iterator.next();
if (next.inEventLoop()) {
isInEventLoop = true;
break;
}
} }
} });
thread.setDaemon(false);
if (!isInEventLoop) { thread.setName(stopTreadName);
EndPoint.this.stopInThread(); thread.start();
}
else {
Thread thread = new Thread(new Runnable() {
@Override
public
void run() {
EndPoint.this.stopInThread();
}
});
thread.setDaemon(false);
thread.setName(stopTreadName);
thread.start();
}
} }
} }