private String getNameInternal() {
StringBuilder name = new StringBuilder(getNamePrefix());
name.append('-');
String id = getId(); if (id != null) {
name.append(id);
} else { if (getAddress() != null) {
name.append(getAddress().getHostAddress());
name.append('-');
} int port = getPortWithOffset(); if (port == 0) { // Auto binding is in use. Check if port is known
name.append("auto-");
name.append(getNameIndex());
port = getLocalPort(); if (port != -1) {
name.append('-');
name.append(port);
}
} else {
name.append(port);
}
} return name.toString();
}
@Override public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) { if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.process", wrapper.getSocket(), status));
} if (wrapper == null) { // Nothing to do. Socket has been closed. return SocketState.CLOSED;
}
S socket = wrapper.getSocket();
// We take complete ownership of the Processor inside of this method to ensure // no other thread can release it while we're using it. Whatever processor is // held by this variable will be associated with the SocketWrapper before this // method returns.
Processor processor = (Processor) wrapper.takeCurrentProcessor(); if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.connectionsGet", processor, socket));
}
// Timeouts are calculated on a dedicated thread and then // dispatched. Because of delays in the dispatch process, the // timeout may no longer be required. Check here and avoid // unnecessary processing. if (SocketEvent.TIMEOUT == status && (processor == null || !processor.isAsync() && !processor.isUpgrade() ||
processor.isAsync() && !processor.checkAsyncTimeoutGeneration())) { // This is effectively a NO-OP return SocketState.OPEN;
}
if (processor != null) { // Make sure an async timeout doesn't fire
getProtocol().removeWaitingProcessor(processor);
} elseif (status == SocketEvent.DISCONNECT || status == SocketEvent.ERROR) { // Nothing to do. Endpoint requested a close and there is no // longer a processor associated with this socket. return SocketState.CLOSED;
}
try { if (processor == null) {
String negotiatedProtocol = wrapper.getNegotiatedProtocol(); // OpenSSL typically returns null whereas JSSE typically // returns "" when no protocol is negotiated if (negotiatedProtocol != null && negotiatedProtocol.length() > 0) {
UpgradeProtocol upgradeProtocol = getProtocol().getNegotiatedProtocol(negotiatedProtocol); if (upgradeProtocol != null) {
processor = upgradeProtocol.getProcessor(wrapper, getProtocol().getAdapter()); if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.processorCreate", processor));
}
} elseif (negotiatedProtocol.equals("http/1.1")) { // Explicitly negotiated the default protocol. // Obtain a processor below.
} else { // TODO: // OpenSSL 1.0.2's ALPN callback doesn't support // failing the handshake with an error if no // protocol can be negotiated. Therefore, we need to // fail the connection here. Once this is fixed, // replace the code below with the commented out // block. if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.negotiatedProcessor.fail",
negotiatedProtocol));
} return SocketState.CLOSED; /* *ToreplacethecodeaboveonceOpenSSL1.1.0isused.// Failed to create processor. This *isabug.thrownewIllegalStateException(sm.getString( *"abstractConnectionHandler.negotiatedProcessor.fail",negotiatedProtocol));
*/
}
}
} if (processor == null) {
processor = recycledProcessors.pop(); if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.processorPop", processor));
}
} if (processor == null) {
processor = getProtocol().createProcessor();
register(processor); if (getLog().isDebugEnabled()) {
getLog().debug(sm.getString("abstractConnectionHandler.processorCreate", processor));
}
}
processor.setSslSupport(wrapper.getSslSupport());
SocketState state = SocketState.CLOSED; do {
state = processor.process(wrapper, status);
if (state == SocketState.UPGRADING) { // Get the HTTP upgrade handler
UpgradeToken upgradeToken = processor.getUpgradeToken(); // Restore leftover input to the wrapper so the upgrade // processor can process it.
ByteBuffer leftOverInput = processor.getLeftoverInput();
wrapper.unRead(leftOverInput); if (upgradeToken == null) { // Assume direct HTTP/2 connection
UpgradeProtocol upgradeProtocol = getProtocol().getUpgradeProtocol("h2c"); if (upgradeProtocol != null) { // Release the Http11 processor to be re-used
release(processor); // Create the upgrade processor
processor = upgradeProtocol.getProcessor(wrapper, getProtocol().getAdapter());
} else { if (getLog().isDebugEnabled()) {
getLog().debug(
sm.getString("abstractConnectionHandler.negotiatedProcessor.fail", "h2c"));
} // Exit loop and trigger appropriate clean-up
state = SocketState.CLOSED;
}
} else {
HttpUpgradeHandler httpUpgradeHandler = upgradeToken.getHttpUpgradeHandler(); // Release the Http11 processor to be re-used
release(processor); // Create the upgrade processor
processor = getProtocol().createUpgradeProcessor(wrapper, upgradeToken); if (getLog().isDebugEnabled()) {
getLog().debug(
sm.getString("abstractConnectionHandler.upgradeCreate", processor, wrapper));
} // Initialise the upgrade handler (which may trigger // some IO using the new protocol which is why the lines // above are necessary) // This cast should be safe. If it fails the error // handling for the surrounding try/catch will deal with // it. if (upgradeToken.getInstanceManager() == null) {
httpUpgradeHandler.init((WebConnection) processor);
} else {
ClassLoader oldCL = upgradeToken.getContextBind().bind(false, null); try {
httpUpgradeHandler.init((WebConnection) processor);
} finally {
upgradeToken.getContextBind().unbind(false, oldCL);
}
} if (httpUpgradeHandler instanceof InternalHttpUpgradeHandler) { if (((InternalHttpUpgradeHandler) httpUpgradeHandler).hasAsyncIO()) { // The handler will initiate all further I/O
state = SocketState.ASYNC_IO;
}
}
}
}
} while (state == SocketState.UPGRADING);
if (state == SocketState.LONG) { // In the middle of processing a request/response. Keep the // socket associated with the processor. Exact requirements // depend on type of long poll
longPoll(wrapper, processor); if (processor.isAsync()) {
getProtocol().addWaitingProcessor(processor);
}
} elseif (state == SocketState.OPEN) { // In keep-alive but between requests. OK to recycle // processor. Continue to poll for the next request.
release(processor);
processor = null;
wrapper.registerReadInterest();
} elseif (state == SocketState.SENDFILE) { // Sendfile in progress. If it fails, the socket will be // closed. If it works, the socket either be added to the // poller (or equivalent) to await more data or processed // if there are any pipe-lined requests remaining.
} elseif (state == SocketState.UPGRADED) { // Don't add sockets back to the poller if this was a // non-blocking write otherwise the poller may trigger // multiple read events which may lead to thread starvation // in the connector. The write() method will add this socket // to the poller if necessary. if (status != SocketEvent.OPEN_WRITE) {
longPoll(wrapper, processor);
getProtocol().addWaitingProcessor(processor);
}
} elseif (state == SocketState.ASYNC_IO) { // Don't add sockets back to the poller. // The handler will initiate all further I/O if (status != SocketEvent.OPEN_WRITE) {
getProtocol().addWaitingProcessor(processor);
}
} elseif (state == SocketState.SUSPENDED) { // Don't add sockets back to the poller. // The resumeProcessing() method will add this socket // to the poller.
} else { // Connection closed. OK to recycle the processor. // Processors handling upgrades require additional clean-up // before release. if (processor != null && processor.isUpgrade()) {
UpgradeToken upgradeToken = processor.getUpgradeToken();
HttpUpgradeHandler httpUpgradeHandler = upgradeToken.getHttpUpgradeHandler();
InstanceManager instanceManager = upgradeToken.getInstanceManager(); if (instanceManager == null) {
httpUpgradeHandler.destroy();
} else {
ClassLoader oldCL = upgradeToken.getContextBind().bind(false, null); try {
httpUpgradeHandler.destroy();
} finally { try {
instanceManager.destroyInstance(httpUpgradeHandler);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e);
getLog().error(sm.getString("abstractConnectionHandler.error"), e);
}
upgradeToken.getContextBind().unbind(false, oldCL);
}
}
}
release(processor);
processor = null;
}
if (processor != null) {
wrapper.setCurrentProcessor(processor);
} return state;
} catch (SocketException e) { // SocketExceptions are normal
getLog().debug(sm.getString("abstractConnectionHandler.socketexception.debug"), e);
} catch (IOException e) { // IOExceptions are normal
getLog().debug(sm.getString("abstractConnectionHandler.ioexception.debug"), e);
} catch (ProtocolException e) { // Protocol exceptions normally mean the client sent invalid or // incomplete data.
getLog().debug(sm.getString("abstractConnectionHandler.protocolexception.debug"), e);
} // Future developers: if you discover any other // rare-but-nonfatal exceptions, catch them here, and log as // above. catch (OutOfMemoryError oome) { // Try and handle this here to give Tomcat a chance to close the // connection and prevent clients waiting until they time out. // Worst case, it isn't recoverable and the attempt at logging // will trigger another OOME.
getLog().error(sm.getString("abstractConnectionHandler.oome"), oome);
} catch (Throwable e) {
ExceptionUtils.handleThrowable(e); // any other exception or error is odd. Here we log it // with "ERROR" level, so it will show up even on // less-than-verbose logs.
getLog().error(sm.getString("abstractConnectionHandler.error"), e);
}
// Make sure socket/processor is removed from the list of current // connections
release(processor); return SocketState.CLOSED;
}
protectedvoid longPoll(SocketWrapperBase<?> socket, Processor processor) { if (!processor.isAsync()) { // This is currently only used with HTTP // Either: // - this is an upgraded connection // - the request line/headers have not been completely // read
socket.registerReadInterest();
}
}
/** *Expectedtobeusedbythehandleroncetheprocessorisnolongerrequired.Caremustbetakentoensure *thatthismethodisonlycalledonceperprocessor,aftertherequestprocessinghascompleted. * *@paramprocessorProcessorbeingreleased(thatwasassociatedwiththesocket)
*/ privatevoid release(Processor processor) { if (processor != null) {
processor.recycle(); if (processor.isUpgrade()) { // While UpgradeProcessor instances should not normally be // present in waitingProcessors there are various scenarios // where this can happen. E.g.: // - when AsyncIO is used // - WebSocket I/O error on non-container thread // Err on the side of caution and always try and remove any // UpgradeProcessor instances from waitingProcessors
getProtocol().removeWaitingProcessor(processor);
} else { // After recycling, only instances of UpgradeProcessorBase // will return true for isUpgrade(). // Instances of UpgradeProcessorBase should not be added to // recycledProcessors since that pool is only for AJP or // HTTP processors
recycledProcessors.push(processor); if (getLog().isDebugEnabled()) {
getLog().debug("Pushed Processor [" + processor + "]");
}
}
}
}
privatefinaltransient ConnectionHandler<?> handler; protectedfinal AtomicInteger size = new AtomicInteger(0);
public RecycledProcessors(ConnectionHandler<?> handler) { this.handler = handler;
}
@SuppressWarnings("sync-override") // Size may exceed cache size a bit
@Override publicboolean push(Processor processor) { int cacheSize = handler.getProtocol().getProcessorCache(); boolean offer = cacheSize == -1 ? true : size.get() < cacheSize; // avoid over growing our cache or add after we have stopped boolean result = false; if (offer) {
result = super.push(processor); if (result) {
size.incrementAndGet();
}
} if (!result) {
handler.unregister(processor);
} return result;
}
@SuppressWarnings("sync-override") // OK if size is too big briefly
@Override public Processor pop() {
Processor result = super.pop(); if (result != null) {
size.decrementAndGet();
} return result;
}
@Override publicsynchronizedvoid clear() {
Processor next = pop(); while (next != null) {
handler.unregister(next);
next = pop();
} super.clear();
size.set(0);
}
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.