Merged branch 'jetty-9.4.x' into 'master'.

This commit is contained in:
Simone Bordet 2016-11-23 12:19:31 +01:00
commit 23753759bb
14 changed files with 178 additions and 73 deletions

View File

@ -182,15 +182,15 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements Connec
} }
@Override @Override
public String toString() public String toConnectionString()
{ {
return String.format("%s@%h(l:%s <-> r:%s,closed=%b)[%s]", return String.format("%s@%x(l:%s <-> r:%s,closed=%b)=>%s",
getClass().getSimpleName(), getClass().getSimpleName(),
this, hashCode(),
getEndPoint().getLocalAddress(), getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress(), getEndPoint().getRemoteAddress(),
closed.get(), closed.get(),
channel); channel);
} }
private class Delegate extends HttpConnection private class Delegate extends HttpConnection

View File

@ -292,15 +292,15 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
} }
@Override @Override
public String toString() public String toConnectionString()
{ {
return String.format("%s@%h(l:%s <-> r:%s)", return String.format("%s@%x[l:%s<->r:%s]",
getClass().getSimpleName(), getClass().getSimpleName(),
this, hashCode(),
getEndPoint().getLocalAddress(), getEndPoint().getLocalAddress(),
getEndPoint().getRemoteAddress()); getEndPoint().getRemoteAddress());
} }
private class Delegate extends HttpConnection private class Delegate extends HttpConnection
{ {
private Delegate(HttpDestination destination) private Delegate(HttpDestination destination)

View File

@ -249,12 +249,16 @@ public abstract class AbstractConnection implements Connection
} }
@Override @Override
public String toString() public final String toString()
{ {
return String.format("%s@%x[%s]", return String.format("%s<-%s",toConnectionString(),getEndPoint());
getClass().getSimpleName(), }
hashCode(),
_endPoint); public String toConnectionString()
{
return String.format("%s@%h",
getClass().getSimpleName(),
this);
} }
private class ReadCallback implements Callback private class ReadCallback implements Callback
@ -274,7 +278,8 @@ public abstract class AbstractConnection implements Connection
@Override @Override
public String toString() public String toString()
{ {
return String.format("AC.ReadCB@%x{%s}", AbstractConnection.this.hashCode(),AbstractConnection.this); return String.format("AC.ReadCB@%h{%s}", AbstractConnection.this,AbstractConnection.this);
} }
} }
} }

View File

@ -427,6 +427,11 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
@Override @Override
public String toString() public String toString()
{
return String.format("%s->%s",toEndPointString(),toConnectionString());
}
public String toEndPointString()
{ {
Class<?> c=getClass(); Class<?> c=getClass();
String name=c.getSimpleName(); String name=c.getSimpleName();
@ -436,20 +441,26 @@ public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
name=c.getSimpleName(); name=c.getSimpleName();
} }
Connection connection = getConnection(); return String.format("%s@%h{%s<->%s,%s,fill=%s,flush=%s,to=%d/%d}",
return String.format("%s@%x{%s<->%s,%s,%s|%s,%d/%d,%s@%x}",
name, name,
hashCode(), this,
getRemoteAddress(), getRemoteAddress(),
getLocalAddress(), getLocalAddress(),
_state.get(), _state.get(),
_fillInterest.toStateString(), _fillInterest.toStateString(),
_writeFlusher.toStateString(), _writeFlusher.toStateString(),
getIdleFor(), getIdleFor(),
getIdleTimeout(), getIdleTimeout());
connection == null ? null : connection.getClass().getSimpleName(),
connection == null ? 0 : connection.hashCode());
} }
public String toConnectionString()
{
Connection connection = getConnection();
if (connection instanceof AbstractConnection)
return ((AbstractConnection)connection).toConnectionString();
return String.format("%s@%x",connection.getClass().getSimpleName(),connection.hashCode());
}
private enum State private enum State
{ {

View File

@ -60,7 +60,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
private abstract class RunnableTask implements Runnable, Invocable private abstract class RunnableTask implements Runnable, Invocable
{ {
private final String _operation; final String _operation;
protected RunnableTask(String op) protected RunnableTask(String op)
{ {
@ -70,7 +70,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
@Override @Override
public String toString() public String toString()
{ {
return ChannelEndPoint.this.toString()+":"+_operation; return String.format("CEP:%s:%s:%s",ChannelEndPoint.this,_operation,getInvocationType());
} }
} }
@ -138,6 +138,13 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
{ {
getWriteFlusher().completeWrite(); getWriteFlusher().completeWrite();
} }
@Override
public String toString()
{
return String.format("CEP:%s:%s:%s->%s",ChannelEndPoint.this,_operation,getInvocationType(),getWriteFlusher());
}
}; };
private final Runnable _runCompleteWriteFillable = new RunnableCloseable("runCompleteWriteFillable") private final Runnable _runCompleteWriteFillable = new RunnableCloseable("runCompleteWriteFillable")
@ -424,7 +431,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
@Override @Override
public String toString() public String toEndPointString()
{ {
// We do a best effort to print the right toString() and that's it. // We do a best effort to print the right toString() and that's it.
try try
@ -433,7 +440,7 @@ public abstract class ChannelEndPoint extends AbstractEndPoint implements Manage
int keyInterests = valid ? _key.interestOps() : -1; int keyInterests = valid ? _key.interestOps() : -1;
int keyReadiness = valid ? _key.readyOps() : -1; int keyReadiness = valid ? _key.readyOps() : -1;
return String.format("%s{io=%d/%d,kio=%d,kro=%d}", return String.format("%s{io=%d/%d,kio=%d,kro=%d}",
super.toString(), super.toEndPointString(),
_currentInterestOps, _currentInterestOps,
_desiredInterestOps, _desiredInterestOps,
keyInterests, keyInterests,

View File

@ -838,4 +838,9 @@ public class ManagedSelector extends AbstractLifeCycle implements Dumpable
} }
} }
} }
public Selector getSelector()
{
return _selector;
}
} }

View File

@ -275,6 +275,11 @@ abstract public class WriteFlusher
{ {
return Invocable.getInvocationType(_callback); return Invocable.getInvocationType(_callback);
} }
public Object getCallback()
{
return _callback;
}
} }
public InvocationType getCallbackInvocationType() public InvocationType getCallbackInvocationType()
@ -523,7 +528,8 @@ abstract public class WriteFlusher
@Override @Override
public String toString() public String toString()
{ {
return String.format("WriteFlusher@%x{%s}", hashCode(), _state.get()); State s = _state.get();
return String.format("WriteFlusher@%x{%s}->%s", hashCode(), s,s instanceof PendingState?((PendingState)s).getCallback():null);
} }
public String toStateString() public String toStateString()

View File

@ -44,6 +44,7 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback; import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Invocable;
/** /**
* A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data * A Connection that acts as an interceptor between an EndPoint providing SSL encrypted data
@ -93,21 +94,52 @@ public class SslConnection extends AbstractConnection
private final boolean _decryptedDirectBuffers = false; private final boolean _decryptedDirectBuffers = false;
private boolean _renegotiationAllowed; private boolean _renegotiationAllowed;
private boolean _closedOutbound; private boolean _closedOutbound;
private final Runnable _runCompletWrite = new Runnable()
private abstract class RunnableTask implements Runnable, Invocable
{
private final String _operation;
protected RunnableTask(String op)
{
_operation=op;
}
@Override
public String toString()
{
return String.format("SSL:%s:%s:%s",SslConnection.this,_operation,getInvocationType());
}
}
private final Runnable _runCompleteWrite = new RunnableTask("runCompleteWrite")
{ {
@Override @Override
public void run() public void run()
{ {
_decryptedEndPoint.getWriteFlusher().completeWrite(); _decryptedEndPoint.getWriteFlusher().completeWrite();
} }
@Override
public InvocationType getInvocationType()
{
return getDecryptedEndPoint().getWriteFlusher().getCallbackInvocationType();
}
}; };
private final Runnable _runFillable = new Runnable()
private final Runnable _runFillable = new RunnableTask("runFillable")
{ {
@Override @Override
public void run() public void run()
{ {
_decryptedEndPoint.getFillInterest().fillable(); _decryptedEndPoint.getFillInterest().fillable();
} }
@Override
public InvocationType getInvocationType()
{
return getDecryptedEndPoint().getFillInterest().getCallbackInvocationType();
}
}; };
Callback _sslReadCallback = new Callback() Callback _sslReadCallback = new Callback()
@ -234,7 +266,7 @@ public class SslConnection extends AbstractConnection
if (_decryptedEndPoint._flushRequiresFillToProgress) if (_decryptedEndPoint._flushRequiresFillToProgress)
{ {
_decryptedEndPoint._flushRequiresFillToProgress = false; _decryptedEndPoint._flushRequiresFillToProgress = false;
_runCompletWrite.run(); _runCompleteWrite.run();
} }
} }
@ -266,7 +298,7 @@ public class SslConnection extends AbstractConnection
} }
@Override @Override
public String toString() public String toConnectionString()
{ {
ByteBuffer b = _encryptedInput; ByteBuffer b = _encryptedInput;
int ei=b==null?-1:b.remaining(); int ei=b==null?-1:b.remaining();
@ -275,22 +307,17 @@ public class SslConnection extends AbstractConnection
b = _decryptedInput; b = _decryptedInput;
int di=b==null?-1:b.remaining(); int di=b==null?-1:b.remaining();
return String.format("SslConnection@%x{%s,eio=%d/%d,di=%d} -> %s", return String.format("%s@%x{%s,eio=%d/%d,di=%d}=>%s",
getClass().getSimpleName(),
hashCode(), hashCode(),
_sslEngine.getHandshakeStatus(), _sslEngine.getHandshakeStatus(),
ei,eo,di, ei,eo,di,
_decryptedEndPoint.getConnection()); ((AbstractConnection)_decryptedEndPoint.getConnection()).toConnectionString());
} }
public class DecryptedEndPoint extends AbstractEndPoint public class DecryptedEndPoint extends AbstractEndPoint
{ {
private boolean _fillRequiresFlushToProgress; private final class WriteCallBack implements Callback, Invocable
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private boolean _underFlown;
private final Callback _writeCallback = new Callback()
{ {
@Override @Override
public void succeeded() public void succeeded()
@ -316,7 +343,7 @@ public class SslConnection extends AbstractConnection
} }
if (fillable) if (fillable)
getFillInterest().fillable(); getFillInterest().fillable();
_runCompletWrite.run(); _runCompleteWrite.run();
} }
@Override @Override
@ -355,7 +382,27 @@ public class SslConnection extends AbstractConnection
} }
},x); },x);
} }
};
@Override
public InvocationType getInvocationType()
{
return getWriteFlusher().getCallbackInvocationType();
}
@Override
public String toString()
{
return String.format("SSL@%h.DEP.writeCallback",SslConnection.this);
}
}
private boolean _fillRequiresFlushToProgress;
private boolean _flushRequiresFillToProgress;
private boolean _cannotAcceptMoreAppDataToFlush;
private boolean _handshaken;
private boolean _underFlown;
private final Callback _writeCallback = new WriteCallBack();
public DecryptedEndPoint() public DecryptedEndPoint()
{ {
@ -452,7 +499,7 @@ public class SslConnection extends AbstractConnection
{ {
// try to flush what is pending // try to flush what is pending
// execute to avoid recursion // execute to avoid recursion
getExecutor().execute(_runCompletWrite); getExecutor().execute(_runCompleteWrite);
} }
} }
} }
@ -738,7 +785,7 @@ public class SslConnection extends AbstractConnection
if (_flushRequiresFillToProgress) if (_flushRequiresFillToProgress)
{ {
_flushRequiresFillToProgress = false; _flushRequiresFillToProgress = false;
getExecutor().execute(_runCompletWrite); getExecutor().execute(_runCompleteWrite);
} }
if (_encryptedInput != null && !_encryptedInput.hasRemaining()) if (_encryptedInput != null && !_encryptedInput.hasRemaining())

View File

@ -77,12 +77,13 @@ public abstract class ProxyConnection extends AbstractConnection
protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback); protected abstract void write(EndPoint endPoint, ByteBuffer buffer, Callback callback);
@Override @Override
public String toString() public String toConnectionString()
{ {
return String.format("%s[l:%d<=>r:%d]", return String.format("%s@%x[l:%d<=>r:%d]",
super.toString(), getClass().getSimpleName(),
getEndPoint().getLocalAddress().getPort(), hashCode(),
getEndPoint().getRemoteAddress().getPort()); getEndPoint().getLocalAddress().getPort(),
getEndPoint().getRemoteAddress().getPort());
} }
private class ProxyIteratingCallback extends IteratingCallback private class ProxyIteratingCallback extends IteratingCallback

View File

@ -559,10 +559,11 @@ public class HttpConnection extends AbstractConnection implements Runnable, Http
} }
@Override @Override
public String toString() public String toConnectionString()
{ {
return String.format("%s[p=%s,g=%s,c=%s]", return String.format("%s@%x[p=%s,g=%s]=>%s",
super.toString(), getClass().getSimpleName(),
hashCode(),
_parser, _parser,
_generator, _generator,
_channel); _channel);

View File

@ -27,6 +27,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.nio.channels.SelectionKey;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,6 +50,7 @@ import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus; import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.LeakTrackingByteBufferPool; import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
import org.eclipse.jetty.io.ManagedSelector;
import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils; import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
@ -69,7 +71,7 @@ public class ThreadStarvationTest
final static int BUFFER_SIZE=1024*1024; final static int BUFFER_SIZE=1024*1024;
final static int BUFFERS=64; final static int BUFFERS=64;
final static int THREADS=5; final static int THREADS=5;
final static int CLIENTS=THREADS*2; final static int CLIENTS=THREADS+2;
@Rule @Rule
public TestTracker tracker = new TestTracker(); public TestTracker tracker = new TestTracker();

View File

@ -154,6 +154,13 @@ public class ServerContainer extends ClientContainer implements javax.websocket.
} }
} }
@Override
protected void doStop() throws Exception
{
mappedCreator.getMappings().reset();
super.doStop();
}
public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException public ServerEndpointMetadata getServerEndpointMetadata(final Class<?> endpoint, final ServerEndpointConfig config) throws DeploymentException
{ {
ServerEndpointMetadata metadata = null; ServerEndpointMetadata metadata = null;

View File

@ -758,11 +758,14 @@ public abstract class AbstractWebSocketConnection extends AbstractConnection imp
} }
@Override @Override
public String toString() public String toConnectionString()
{ {
return String.format("%s@%X{endp=%s,ios=%s,f=%s,g=%s,p=%s}",getClass().getSimpleName(),hashCode(),getEndPoint(),ioState,flusher,generator,parser); return String.format("%s@%x[ios=%s,f=%s,g=%s,p=%s]",
getClass().getSimpleName(),
hashCode(),
ioState,flusher,generator,parser);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {

View File

@ -44,6 +44,7 @@ import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.util.annotation.ManagedAttribute; import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject; import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable; import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Log;
@ -55,11 +56,13 @@ import org.eclipse.jetty.websocket.servlet.WebSocketCreator;
* Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects. * Inline Servlet Filter to capture WebSocket upgrade requests and perform path mappings to {@link WebSocketCreator} objects.
*/ */
@ManagedObject("WebSocket Upgrade Filter") @ManagedObject("WebSocket Upgrade Filter")
public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter, MappedWebSocketCreator, Dumpable public class WebSocketUpgradeFilter extends AbstractLifeCycle implements Filter, MappedWebSocketCreator, Dumpable
{ {
public static final String CONTEXT_ATTRIBUTE_KEY = "contextAttributeKey"; public static final String CONTEXT_ATTRIBUTE_KEY = "contextAttributeKey";
private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class); private static final Logger LOG = Log.getLogger(WebSocketUpgradeFilter.class);
private boolean localMapper;
private boolean localFactory;
public static WebSocketUpgradeFilter configureContext(ServletContextHandler context) throws ServletException public static WebSocketUpgradeFilter configureContext(ServletContextHandler context) throws ServletException
{ {
// Prevent double configure // Prevent double configure
@ -162,8 +165,14 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
@Override @Override
public void destroy() public void destroy()
{ {
factory.cleanup(); if (localFactory)
super.destroy(); {
factory.cleanup();
}
if (localMapper)
{
mappedWebSocketCreator.getMappings().reset();
}
} }
@Override @Override
@ -281,21 +290,22 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
try try
{ {
mappedWebSocketCreator = (MappedWebSocketCreator) config.getServletContext().getAttribute(CREATOR_KEY); ServletContext context = config.getServletContext();
mappedWebSocketCreator = (MappedWebSocketCreator) context.getAttribute(CREATOR_KEY);
if (mappedWebSocketCreator == null) if (mappedWebSocketCreator == null)
{ {
mappedWebSocketCreator = new DefaultMappedWebSocketCreator(); mappedWebSocketCreator = new DefaultMappedWebSocketCreator();
localMapper = true;
} }
factory = (WebSocketServerFactory) config.getServletContext().getAttribute(FACTORY_KEY); factory = (WebSocketServerFactory) context.getAttribute(FACTORY_KEY);
if (factory == null) if (factory == null)
{ {
factory = new WebSocketServerFactory(policy, bufferPool); factory = new WebSocketServerFactory(policy, bufferPool);
localFactory = true;
} }
factory.init(config.getServletContext()); factory.init(context);
addBean(factory, true);
// TODO: Policy isn't from attributes
String max = config.getInitParameter("maxIdleTime"); String max = config.getInitParameter("maxIdleTime");
if (max != null) if (max != null)
@ -328,7 +338,7 @@ public class WebSocketUpgradeFilter extends ContainerLifeCycle implements Filter
key = WebSocketUpgradeFilter.class.getName(); key = WebSocketUpgradeFilter.class.getName();
} }
setToAttribute(config.getServletContext(), key); setToAttribute(context, key);
factory.start(); factory.start();
} }