332937 Added Destroyable Dumpable interfaces and reworked dependent lifecycles, specially of JNDI
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@2721 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
f807e15c77
commit
f9458ee5ca
|
@ -14,7 +14,7 @@ jetty-7.3.0-SNAPSHOT
|
|||
+ 332703 Cleanup context scope JNDI at stop
|
||||
+ 332796 Annotations inheritance does not work with jetty7
|
||||
+ 332799 100% CPU on redeploy session invalidation
|
||||
+ 332937 Added Destroyable interface and reworked dependent lifecycles, specially of JNDI
|
||||
+ 332937 Added Destroyable Dumpable interfaces and reworked dependent lifecycles, specially of JNDI
|
||||
+ 333247 fix api compat issue in ConstraintSecurityHandler
|
||||
+ 333415 wired up HttpInput.available and added test harnesses
|
||||
+ 333481 Handle UTF-32 codepoints in decode and encode
|
||||
|
|
|
@ -43,6 +43,8 @@ public class LikeJettyXml
|
|||
System.setProperty("jetty.home",jetty_home);
|
||||
|
||||
Server server = new Server();
|
||||
server.setDumpAfterStart(true);
|
||||
server.setDumpBeforeStop(true);
|
||||
|
||||
// Setup JMX
|
||||
MBeanContainer mbContainer=new MBeanContainer(ManagementFactory.getPlatformMBeanServer());
|
||||
|
@ -134,8 +136,6 @@ public class LikeJettyXml
|
|||
|
||||
server.start();
|
||||
|
||||
System.err.println(server.dump());
|
||||
|
||||
server.join();
|
||||
}
|
||||
|
||||
|
|
|
@ -590,7 +590,8 @@ public class SelectChannelEndPoint extends ChannelEndPoint implements AsyncEndPo
|
|||
{
|
||||
synchronized(this)
|
||||
{
|
||||
return "SCEP@" + hashCode() + " [d=" + _dispatched + ",io=" + _interestOps+
|
||||
return "SCEP@" + hashCode() + _channel+
|
||||
"[d=" + _dispatched + ",io=" + _interestOps+
|
||||
",w=" + _writable + ",rb=" + _readBlocked + ",wb=" + _writeBlocked + "]";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,22 @@ import java.nio.channels.SelectionKey;
|
|||
import java.nio.channels.Selector;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.io.ConnectedEndPoint;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.thread.Timeout;
|
||||
import org.eclipse.jetty.util.thread.Timeout.Task;
|
||||
|
@ -41,7 +49,7 @@ import org.eclipse.jetty.util.thread.Timeout.Task;
|
|||
* This class works around a number of know JVM bugs. For details
|
||||
* see http://wiki.eclipse.org/Jetty/Feature/JVM_NIO_Bug
|
||||
*/
|
||||
public abstract class SelectorManager extends AbstractLifeCycle
|
||||
public abstract class SelectorManager extends AbstractLifeCycle implements Dumpable
|
||||
{
|
||||
// TODO Tune these by approx system speed.
|
||||
private static final int __JVMBUG_THRESHHOLD=Integer.getInteger("org.eclipse.jetty.io.nio.JVMBUG_THRESHHOLD",0).intValue();
|
||||
|
@ -281,39 +289,25 @@ public abstract class SelectorManager extends AbstractLifeCycle
|
|||
*/
|
||||
protected abstract SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectorManager.SelectSet selectSet, SelectionKey sKey) throws IOException;
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void dump()
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
for (final SelectSet set :_selectSet)
|
||||
{
|
||||
Thread selecting = set._selecting;
|
||||
Log.info("SelectSet "+set._setID+" : "+selecting);
|
||||
if (selecting!=null)
|
||||
{
|
||||
StackTraceElement[] trace =selecting.getStackTrace();
|
||||
if (trace!=null)
|
||||
{
|
||||
for (StackTraceElement e : trace)
|
||||
{
|
||||
Log.info("\tat "+e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set.addChange(new Runnable(){
|
||||
public void run()
|
||||
{
|
||||
set.dump();
|
||||
}
|
||||
});
|
||||
}
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(_selectSet));
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public class SelectSet
|
||||
public class SelectSet implements Dumpable
|
||||
{
|
||||
private final int _setID;
|
||||
private final Timeout _timeout;
|
||||
|
@ -837,20 +831,67 @@ public abstract class SelectorManager extends AbstractLifeCycle
|
|||
_selector=null;
|
||||
}
|
||||
}
|
||||
|
||||
public void dump()
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
synchronized (System.err)
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append(" id=").append(String.valueOf(_setID)).append("\n");
|
||||
|
||||
Thread selecting = _selecting;
|
||||
|
||||
Object where = "not selecting";
|
||||
StackTraceElement[] trace =selecting==null?null:selecting.getStackTrace();
|
||||
if (trace!=null)
|
||||
{
|
||||
Selector selector=_selector;
|
||||
Log.info("SelectSet "+_setID+" "+selector.keys().size());
|
||||
for (SelectionKey key: selector.keys())
|
||||
for (StackTraceElement t:trace)
|
||||
if (t.getClassName().startsWith("org.eclipse.jetty."))
|
||||
{
|
||||
where=t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Selector selector=_selector;
|
||||
final ArrayList<Object> dump = new ArrayList<Object>(selector.keys().size()*2);
|
||||
dump.add(where);
|
||||
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
addChange(new Runnable(){
|
||||
public void run()
|
||||
{
|
||||
if (key.isValid())
|
||||
Log.info(key.channel()+" "+key.interestOps()+" "+key.readyOps()+" "+key.attachment());
|
||||
else
|
||||
Log.info(key.channel()+" - - "+key.attachment());
|
||||
dumpKeyState(dump);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
latch.await(5,TimeUnit.SECONDS);
|
||||
}
|
||||
catch(InterruptedException e)
|
||||
{
|
||||
Log.ignore(e);
|
||||
}
|
||||
AggregateLifeCycle.dump(out,indent,dump);
|
||||
}
|
||||
|
||||
public void dumpKeyState(List<Object> dumpto)
|
||||
{
|
||||
Selector selector=_selector;
|
||||
dumpto.add(selector+" keys="+selector.keys().size());
|
||||
for (SelectionKey key: selector.keys())
|
||||
{
|
||||
if (key.isValid())
|
||||
dumpto.add(key.attachment()+" "+key.interestOps()+" "+key.readyOps());
|
||||
else
|
||||
dumpto.add(key.attachment()+" - - ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -962,7 +962,7 @@ public class SslSelectChannelEndPoint extends SelectChannelEndPoint
|
|||
{
|
||||
final NIOBuffer i=_inNIOBuffer;
|
||||
final NIOBuffer o=_outNIOBuffer;
|
||||
return super.toString()+","+_engine.getHandshakeStatus()+", in/out="+
|
||||
return "SSL"+super.toString()+","+_engine.getHandshakeStatus()+", in/out="+
|
||||
(i==null?0:_inNIOBuffer.length())+"/"+(o==null?0:o.length())+" "+_result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
AggregateLifeCycle: A LifeCycle holding other LifeCycles
|
||||
dumpStdErr():Object:INFO:Dump the nested Object state to StdErr
|
|
@ -5,6 +5,7 @@ name: Name of the thread pool
|
|||
daemon: Is pool thread using daemon thread
|
||||
threadsPriority: The priority of threads in the pool
|
||||
maxIdleTimeMs: Maximum time a thread may be idle in ms
|
||||
detailedDump: Full stack detail in dump output
|
||||
dump(): Dump thread state
|
||||
stopThread(long): Stop a pool thread
|
||||
stopThread(long)[0]: id:Thread ID
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
|
||||
<Set name="minThreads">10</Set>
|
||||
<Set name="maxThreads">200</Set>
|
||||
<Set name="detailedDump">false</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
|
@ -72,5 +73,7 @@
|
|||
<Set name="sendServerVersion">true</Set>
|
||||
<Set name="sendDateHeader">true</Set>
|
||||
<Set name="gracefulShutdown">1000</Set>
|
||||
<Set name="dumpAfterStart">false</Set>
|
||||
<Set name="dumpBeforeStop">false</Set>
|
||||
|
||||
</Configure>
|
||||
|
|
|
@ -24,13 +24,14 @@ import javax.servlet.ServletRequest;
|
|||
import org.eclipse.jetty.http.HttpBuffers;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeaders;
|
||||
import org.eclipse.jetty.http.HttpMethods;
|
||||
import org.eclipse.jetty.http.HttpSchemes;
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.EofException;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
||||
|
@ -51,7 +52,7 @@ import org.eclipse.jetty.util.thread.ThreadPool;
|
|||
*
|
||||
*
|
||||
*/
|
||||
public abstract class AbstractConnector extends HttpBuffers implements Connector
|
||||
public abstract class AbstractConnector extends HttpBuffers implements Connector, Dumpable
|
||||
{
|
||||
private String _name;
|
||||
|
||||
|
@ -98,13 +99,6 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public final Buffer newBuffer(int size)
|
||||
{
|
||||
// TODO remove once no overrides established
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public Buffer newRequestBuffer(int size)
|
||||
|
@ -1137,4 +1131,18 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
|||
oldValue = valueHolder.get();
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
private int _graceful=0;
|
||||
private boolean _stopAtShutdown;
|
||||
private int _maxCookieVersion=1;
|
||||
private boolean _dumpAfterStart=false;
|
||||
private boolean _dumpBeforeStop=false;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -205,6 +207,38 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
addBean(_threadPool);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if {@link #dumpStdErr()} is called after starting
|
||||
*/
|
||||
public boolean isDumpAfterStart()
|
||||
{
|
||||
return _dumpAfterStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dumpAfterStart true if {@link #dumpStdErr()} is called after starting
|
||||
*/
|
||||
public void setDumpAfterStart(boolean dumpAfterStart)
|
||||
{
|
||||
_dumpAfterStart = dumpAfterStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if {@link #dumpStdErr()} is called before stopping
|
||||
*/
|
||||
public boolean isDumpBeforeStop()
|
||||
{
|
||||
return _dumpBeforeStop;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dumpBeforeStop true if {@link #dumpStdErr()} is called before stopping
|
||||
*/
|
||||
public void setDumpBeforeStop(boolean dumpBeforeStop)
|
||||
{
|
||||
_dumpBeforeStop = dumpBeforeStop;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
|
@ -239,8 +273,9 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
}
|
||||
}
|
||||
}
|
||||
if (Log.isDebugEnabled())
|
||||
System.err.println(dump());
|
||||
|
||||
if (isDumpAfterStart())
|
||||
dumpStdErr();
|
||||
|
||||
mex.ifExceptionThrow();
|
||||
}
|
||||
|
@ -249,6 +284,9 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
if (isDumpBeforeStop())
|
||||
dumpStdErr();
|
||||
|
||||
MultiException mex=new MultiException();
|
||||
|
||||
if (_graceful>0)
|
||||
|
@ -573,8 +611,7 @@ public class Server extends HandlerWrapper implements Attributes
|
|||
dumpThis(out);
|
||||
dump(out,indent,TypeUtil.asList(getHandlers()),getBeans(),TypeUtil.asList(_connectors));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* A handler that can be gracefully shutdown.
|
||||
* Called by doStop if a {@link #setGracefulShutdown} period is set.
|
||||
|
|
|
@ -93,7 +93,7 @@ public abstract class AbstractHandler extends AggregateLifeCycle implements Hand
|
|||
/* ------------------------------------------------------------ */
|
||||
public void dumpThis(Appendable out) throws IOException
|
||||
{
|
||||
out.append(toString()).append(isStarted()?" started":" STOPPED").append('\n');
|
||||
out.append(toString()).append(' ').append(getState()).append('\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@ import java.net.Socket;
|
|||
import java.nio.channels.SelectionKey;
|
||||
import java.nio.channels.ServerSocketChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.eclipse.jetty.continuation.Continuation;
|
||||
import org.eclipse.jetty.io.ConnectedEndPoint;
|
||||
|
@ -29,6 +31,7 @@ import org.eclipse.jetty.io.nio.SelectorManager;
|
|||
import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
|
||||
import org.eclipse.jetty.server.HttpConnection;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.thread.Timeout.Task;
|
||||
|
||||
|
@ -65,45 +68,7 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
private int _lowResourcesMaxIdleTime;
|
||||
private int _localPort=-1;
|
||||
|
||||
private final SelectorManager _manager = new SelectorManager()
|
||||
{
|
||||
@Override
|
||||
public boolean dispatch(Runnable task)
|
||||
{
|
||||
return getThreadPool().dispatch(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointClosed(final SelectChannelEndPoint endpoint)
|
||||
{
|
||||
connectionClosed(endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointOpened(SelectChannelEndPoint endpoint)
|
||||
{
|
||||
// TODO handle max connections and low resources
|
||||
connectionOpened(endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
|
||||
{
|
||||
connectionUpgraded(oldConnection,endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Connection newConnection(SocketChannel channel,SelectChannelEndPoint endpoint)
|
||||
{
|
||||
return SelectChannelConnector.this.newConnection(channel,endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException
|
||||
{
|
||||
return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
|
||||
}
|
||||
};
|
||||
private final SelectorManager _manager = new ConnectorSelectorManager();
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/**
|
||||
|
@ -337,10 +302,54 @@ public class SelectChannelConnector extends AbstractNIOConnector
|
|||
};
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public void dump()
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
Log.info("channel "+_acceptChannel+(_acceptChannel.isOpen()?" is open":" is closed"));
|
||||
_manager.dump();
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(new Object[]{_acceptChannel,_acceptChannel.isOpen()?"OPEN":"CLOSED",_manager}));
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
private final class ConnectorSelectorManager extends SelectorManager
|
||||
{
|
||||
@Override
|
||||
public boolean dispatch(Runnable task)
|
||||
{
|
||||
return getThreadPool().dispatch(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointClosed(final SelectChannelEndPoint endpoint)
|
||||
{
|
||||
connectionClosed(endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointOpened(SelectChannelEndPoint endpoint)
|
||||
{
|
||||
// TODO handle max connections and low resources
|
||||
connectionOpened(endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endPointUpgraded(ConnectedEndPoint endpoint, Connection oldConnection)
|
||||
{
|
||||
connectionUpgraded(oldConnection,endpoint.getConnection());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Connection newConnection(SocketChannel channel,SelectChannelEndPoint endpoint)
|
||||
{
|
||||
return SelectChannelConnector.this.newConnection(channel,endpoint);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey sKey) throws IOException
|
||||
{
|
||||
return SelectChannelConnector.this.newEndPoint(channel,selectSet,sKey);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
AbstractHandler: Jetty Handler.
|
||||
dump(): dump the handler structure as a string
|
||||
AbstractHandler: Jetty Handler.
|
|
@ -5,3 +5,5 @@ sendServerVersion: If true include the server version in HTTP headers
|
|||
threadPool: MObject:The server Thread Pool
|
||||
contexts: MMBean:RO:The contexts of this server
|
||||
startupTime: MBean:RO:The startup time, in milliseconds, since January 1st 1970
|
||||
dumpAfterStart: RW:Dump state to stderr after start
|
||||
dumpBeforeStop: RW:Dump state to stderr before stop
|
||||
|
|
|
@ -14,6 +14,10 @@
|
|||
|
||||
package org.eclipse.jetty.util.thread;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
@ -25,10 +29,12 @@ import java.util.concurrent.atomic.AtomicLong;
|
|||
|
||||
import org.eclipse.jetty.util.BlockingArrayQueue;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.AggregateLifeCycle;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
||||
public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, Executor
|
||||
public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, Executor, Dumpable
|
||||
{
|
||||
private final AtomicInteger _threadsStarted = new AtomicInteger();
|
||||
private final AtomicInteger _threadsIdle = new AtomicInteger();
|
||||
|
@ -44,6 +50,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
|
|||
private int _priority=Thread.NORM_PRIORITY;
|
||||
private boolean _daemon=false;
|
||||
private int _maxStopTime=100;
|
||||
private boolean _detailedDump=false;
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/** Construct
|
||||
|
@ -321,7 +328,18 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
|
|||
return _daemon;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean isDetailedDump()
|
||||
{
|
||||
return _detailedDump;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void setDetailedDump(boolean detailedDump)
|
||||
{
|
||||
_detailedDump = detailedDump;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public boolean dispatch(Runnable job)
|
||||
{
|
||||
|
@ -427,12 +445,71 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
|
|||
return new Thread(runnable);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public String dump()
|
||||
{
|
||||
return AggregateLifeCycle.dump(this);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
List<Object> dump = new ArrayList<Object>(getMaxThreads());
|
||||
for (final Thread thread: _threads)
|
||||
{
|
||||
final StackTraceElement[] trace=thread.getStackTrace();
|
||||
boolean inIdleJobPoll=false;
|
||||
for (StackTraceElement t : trace)
|
||||
{
|
||||
if ("idleJobPoll".equals(t.getMethodName()))
|
||||
{
|
||||
inIdleJobPoll=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
final boolean idle=inIdleJobPoll;
|
||||
|
||||
if (_detailedDump)
|
||||
{
|
||||
dump.add(new Dumpable()
|
||||
{
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
out.append(String.valueOf(thread.getId())).append(' ').append(thread.getName()).append(' ').append(thread.getState().toString()).append(idle?" IDLE":"").append('\n');
|
||||
if (!idle)
|
||||
AggregateLifeCycle.dump(out,indent,Arrays.asList(trace));
|
||||
}
|
||||
|
||||
public String dump()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
dump.add(thread.getId()+" "+thread.getName()+" "+thread.getState()+" @ "+trace[0]+(idle?" IDLE":""));
|
||||
}
|
||||
}
|
||||
|
||||
out.append(String.valueOf(this)).append("\n");
|
||||
AggregateLifeCycle.dump(out,indent,dump);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return _name+"{"+getMinThreads()+"<="+getIdleThreads()+"<="+getThreads()+"/"+getMaxThreads()+","+(_jobs==null?-1:_jobs.size())+"}";
|
||||
}
|
||||
|
||||
private Runnable idleJobPoll() throws InterruptedException
|
||||
{
|
||||
return _jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private Runnable _runnable = new Runnable()
|
||||
|
@ -477,7 +554,7 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
|
|||
return;
|
||||
}
|
||||
}
|
||||
job=_jobs.poll(_maxIdleTimeMs,TimeUnit.MILLISECONDS);
|
||||
job=idleJobPoll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -504,20 +581,6 @@ public class QueuedThreadPool extends AbstractLifeCycle implements ThreadPool, E
|
|||
}
|
||||
};
|
||||
|
||||
public String dump()
|
||||
{
|
||||
StringBuilder buf = new StringBuilder();
|
||||
|
||||
for (Thread thread: _threads)
|
||||
{
|
||||
buf.append(thread.getId()).append(" ").append(thread.getName()).append(" ").append(thread.getState()).append(":\n");
|
||||
for (StackTraceElement element : thread.getStackTrace())
|
||||
buf.append(" at ").append(element.toString()).append('\n');
|
||||
}
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param id The thread ID to stop.
|
||||
|
|
Loading…
Reference in New Issue