diff --git a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc
index 1a23358bf2c..abc80009d30 100644
--- a/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc
+++ b/documentation/jetty-documentation/src/main/asciidoc/programming-guide/client/client-io-arch.adoc
@@ -33,7 +33,7 @@ The `ClientConnector` primarily wraps the link:{javadoc-url}/org/eclipse/jetty/i
* a thread pool (in form of an `java.util.concurrent.Executor`)
* a scheduler (in form of `org.eclipse.jetty.util.thread.Scheduler`)
-* a byte buffer pool (in form of `org.eclipse.jetty.io.ByteBufferPool`)
+* a byte buffer pool (in form of `org.eclipse.jetty.io.RetainableByteBufferPool`)
* a TLS factory (in form of `org.eclipse.jetty.util.ssl.SslContextFactory.Client`)
The `ClientConnector` is where you want to set those components after you have configured them.
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java
index 8a3e69f75b1..9f2c92c2b4e 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/HTTP2Docs.java
@@ -72,7 +72,7 @@ public class HTTP2Docs
}
// Get the content buffer.
- ByteBuffer byteBuffer = data.frame().getData();
+ ByteBuffer byteBuffer = data.frame().getByteBuffer();
// Unwrap the Data object, converting it to a Chunk.
// The Data.release() semantic is maintained in the completion of the Callback.
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java
index e75148d384b..3cbb717b391 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/ClientConnectorDocs.java
@@ -387,7 +387,7 @@ public class ClientConnectorDocs
// Wrap the "telnet" ClientConnectionFactory with the SslClientConnectionFactory.
connectionFactory = new SslClientConnectionFactory(clientConnector.getSslContextFactory(),
- clientConnector.getByteBufferPool(), clientConnector.getExecutor(), connectionFactory);
+ clientConnector.getRetainableByteBufferPool(), clientConnector.getExecutor(), connectionFactory);
// We will obtain a SslConnection now.
CompletableFuture connectionPromise = new Promise.Completable<>();
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java
index 9612d5204e5..90857287c2f 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http/HTTPClientDocs.java
@@ -63,7 +63,6 @@ import org.eclipse.jetty.http2.client.transport.ClientConnectionFactoryOverHTTP2
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.http3.client.HTTP3Client;
import org.eclipse.jetty.http3.client.transport.HttpClientTransportOverHTTP3;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.Content;
@@ -334,14 +333,13 @@ public class HTTPClientDocs
// An event happens in some other class, in some other thread.
class ContentPublisher
{
- void publish(ByteBufferPool bufferPool, byte[] bytes, boolean lastContent)
+ void publish(byte[] bytes, boolean lastContent)
{
// Wrap the bytes into a new ByteBuffer.
ByteBuffer buffer = ByteBuffer.wrap(bytes);
- // Offer the content, and release the ByteBuffer
- // to the pool when the Callback is completed.
- content.write(buffer, Callback.from(() -> bufferPool.release(buffer)));
+ // Write the content.
+ content.write(buffer, Callback.NOOP);
// Close AsyncRequestContent when all the content is arrived.
if (lastContent)
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
index 940138f7df9..7797bfc87a5 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/client/http2/HTTP2ClientDocs.java
@@ -254,7 +254,7 @@ public class HTTP2ClientDocs
}
// Get the content buffer.
- ByteBuffer buffer = data.frame().getData();
+ ByteBuffer buffer = data.frame().getByteBuffer();
// Consume the buffer, here - as an example - just log it.
System.getLogger("http2").log(INFO, "Consuming buffer {0}", buffer);
@@ -368,7 +368,7 @@ public class HTTP2ClientDocs
}
// The pushed stream "response" content bytes.
- ByteBuffer buffer = data.frame().getData();
+ ByteBuffer buffer = data.frame().getByteBuffer();
// Consume the buffer and release the Data object.
data.release();
diff --git a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
index 291048af5af..4852c39e829 100644
--- a/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
+++ b/documentation/jetty-documentation/src/main/java/org/eclipse/jetty/docs/programming/server/http2/HTTP2ServerDocs.java
@@ -159,7 +159,7 @@ public class HTTP2ServerDocs
}
// Get the content buffer.
- ByteBuffer buffer = data.frame().getData();
+ ByteBuffer buffer = data.frame().getByteBuffer();
// Consume the buffer, here - as an example - just log it.
System.getLogger("http2").log(INFO, "Consuming buffer {0}", buffer);
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java
index 801d6e13acd..8e70421dc53 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/AbstractConnectorHttpClientTransport.java
@@ -52,7 +52,7 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC
{
HttpClient httpClient = getHttpClient();
connector.setBindAddress(httpClient.getBindAddress());
- connector.setByteBufferPool(httpClient.getByteBufferPool());
+ connector.setRetainableByteBufferPool(httpClient.getRetainableByteBufferPool());
connector.setConnectBlocking(httpClient.isConnectBlocking());
connector.setConnectTimeout(Duration.ofMillis(httpClient.getConnectTimeout()));
connector.setExecutor(httpClient.getExecutor());
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java
index 537a74f540e..88e734451e1 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/ContentDecoder.java
@@ -20,6 +20,7 @@ import java.util.Map;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.RetainableByteBuffer;
/**
* {@link ContentDecoder} decodes content bytes of a response.
@@ -29,21 +30,14 @@ import org.eclipse.jetty.http.HttpHeader;
public interface ContentDecoder
{
/**
- *
Decodes the bytes in the given {@code buffer} and returns decoded bytes, if any.
+ *
Decodes the bytes in the given {@code buffer} and returns the decoded bytes.
+ *
The returned {@link RetainableByteBuffer} containing the decoded bytes may
+ * be empty and must be released via {@link RetainableByteBuffer#release()}.
*
* @param buffer the buffer containing encoded bytes
- * @return a buffer containing decoded bytes, if any
+ * @return a buffer containing decoded bytes that must be released
*/
- public abstract ByteBuffer decode(ByteBuffer buffer);
-
- /**
- *
Releases the ByteBuffer returned by {@link #decode(ByteBuffer)}.
- *
- * @param decoded the ByteBuffer returned by {@link #decode(ByteBuffer)}
- */
- public default void release(ByteBuffer decoded)
- {
- }
+ public abstract RetainableByteBuffer decode(ByteBuffer buffer);
/**
* Factory for {@link ContentDecoder}s; subclasses must implement {@link #newContentDecoder()}.
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java
index 304f2d3765e..aa09fa56785 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/GZIPContentDecoder.java
@@ -13,9 +13,8 @@
package org.eclipse.jetty.client;
-import java.nio.ByteBuffer;
-
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
/**
* {@link ContentDecoder} for the "gzip" encoding.
@@ -34,13 +33,13 @@ public class GZIPContentDecoder extends org.eclipse.jetty.http.GZIPContentDecode
this(null, bufferSize);
}
- public GZIPContentDecoder(ByteBufferPool byteBufferPool, int bufferSize)
+ public GZIPContentDecoder(RetainableByteBufferPool retainableByteBufferPool, int bufferSize)
{
- super(byteBufferPool, bufferSize);
+ super(retainableByteBufferPool, bufferSize);
}
@Override
- protected boolean decodedChunk(ByteBuffer chunk)
+ protected boolean decodedChunk(RetainableByteBuffer chunk)
{
super.decodedChunk(chunk);
return true;
@@ -51,8 +50,8 @@ public class GZIPContentDecoder extends org.eclipse.jetty.http.GZIPContentDecode
*/
public static class Factory extends ContentDecoder.Factory
{
+ private final RetainableByteBufferPool retainableByteBufferPool;
private final int bufferSize;
- private final ByteBufferPool byteBufferPool;
public Factory()
{
@@ -64,22 +63,22 @@ public class GZIPContentDecoder extends org.eclipse.jetty.http.GZIPContentDecode
this(null, bufferSize);
}
- public Factory(ByteBufferPool byteBufferPool)
+ public Factory(RetainableByteBufferPool retainableByteBufferPool)
{
- this(byteBufferPool, DEFAULT_BUFFER_SIZE);
+ this(retainableByteBufferPool, DEFAULT_BUFFER_SIZE);
}
- public Factory(ByteBufferPool byteBufferPool, int bufferSize)
+ public Factory(RetainableByteBufferPool retainableByteBufferPool, int bufferSize)
{
super("gzip");
- this.byteBufferPool = byteBufferPool;
+ this.retainableByteBufferPool = retainableByteBufferPool;
this.bufferSize = bufferSize;
}
@Override
public ContentDecoder newContentDecoder()
{
- return new GZIPContentDecoder(byteBufferPool, bufferSize);
+ return new GZIPContentDecoder(retainableByteBufferPool, bufferSize);
}
}
}
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
index 881b797fdbf..ee7660f96f7 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java
@@ -49,10 +49,8 @@ import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
-import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
import org.eclipse.jetty.util.Fields;
@@ -201,11 +199,9 @@ public class HttpClient extends ContainerLifeCycle
int maxBucketSize = executor instanceof ThreadPool.SizedThreadPool
? ((ThreadPool.SizedThreadPool)executor).getMaxThreads() / 2
: ProcessorUtils.availableProcessors() * 2;
- ByteBufferPool byteBufferPool = getByteBufferPool();
- if (byteBufferPool == null)
- setByteBufferPool(new MappedByteBufferPool(2048, maxBucketSize));
- if (getBean(RetainableByteBufferPool.class) == null)
- addBean(new ArrayRetainableByteBufferPool(0, 2048, 65536, maxBucketSize));
+ RetainableByteBufferPool retainableByteBufferPool = getRetainableByteBufferPool();
+ if (retainableByteBufferPool == null)
+ setRetainableByteBufferPool(new ArrayRetainableByteBufferPool(0, 2048, 65536, maxBucketSize));
Scheduler scheduler = getScheduler();
if (scheduler == null)
{
@@ -224,7 +220,7 @@ public class HttpClient extends ContainerLifeCycle
handlers.put(new ProxyAuthenticationProtocolHandler(this));
handlers.put(new UpgradeProtocolHandler());
- decoderFactories.put(new GZIPContentDecoder.Factory(byteBufferPool));
+ decoderFactories.put(new GZIPContentDecoder.Factory(retainableByteBufferPool));
cookieManager = newCookieManager();
cookieStore = cookieManager.getCookieStore();
@@ -650,19 +646,19 @@ public class HttpClient extends ContainerLifeCycle
}
/**
- * @return the {@link ByteBufferPool} of this HttpClient
+ * @return the {@link RetainableByteBufferPool} of this HttpClient
*/
- public ByteBufferPool getByteBufferPool()
+ public RetainableByteBufferPool getRetainableByteBufferPool()
{
- return connector.getByteBufferPool();
+ return connector.getRetainableByteBufferPool();
}
/**
- * @param byteBufferPool the {@link ByteBufferPool} of this HttpClient
+ * @param retainableByteBufferPool the {@link RetainableByteBufferPool} of this HttpClient
*/
- public void setByteBufferPool(ByteBufferPool byteBufferPool)
+ public void setRetainableByteBufferPool(RetainableByteBufferPool retainableByteBufferPool)
{
- connector.setByteBufferPool(byteBufferPool);
+ connector.setRetainableByteBufferPool(retainableByteBufferPool);
}
/**
@@ -1156,6 +1152,6 @@ public class HttpClient extends ContainerLifeCycle
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
- return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory);
+ return new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), connectionFactory);
}
}
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpReceiver.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpReceiver.java
index 0bc75047e44..575bcab02ba 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpReceiver.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/internal/HttpReceiver.java
@@ -14,7 +14,6 @@
package org.eclipse.jetty.client.internal;
import java.net.URI;
-import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
@@ -27,8 +26,8 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.io.content.ContentSourceTransformer;
-import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.thread.AutoLock;
import org.eclipse.jetty.util.thread.SerializedInvoker;
@@ -578,17 +577,17 @@ public abstract class HttpReceiver
_chunk.retain();
if (LOG.isDebugEnabled())
LOG.debug("decoding: {}", _chunk);
- ByteBuffer decodedBuffer = _decoder.decode(_chunk.getByteBuffer());
+ RetainableByteBuffer decodedBuffer = _decoder.decode(_chunk.getByteBuffer());
if (LOG.isDebugEnabled())
- LOG.debug("decoded: {}", BufferUtil.toDetailString(decodedBuffer));
+ LOG.debug("decoded: {}", decodedBuffer);
- if (BufferUtil.hasContent(decodedBuffer))
+ if (decodedBuffer != null && decodedBuffer.hasRemaining())
{
// The decoded ByteBuffer is a transformed "copy" of the
// compressed one, so it has its own reference counter.
if (LOG.isDebugEnabled())
LOG.debug("returning decoded content");
- return Content.Chunk.from(decodedBuffer, false, _decoder::release);
+ return Content.Chunk.asChunk(decodedBuffer.getByteBuffer(), false, decodedBuffer);
}
else
{
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpReceiverOverHTTP.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpReceiverOverHTTP.java
index 3d81b80a0e1..c1ebf22175c 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpReceiverOverHTTP.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpReceiverOverHTTP.java
@@ -66,7 +66,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
parser.setHeaderCacheSize(httpTransport.getHeaderCacheSize());
parser.setHeaderCacheCaseSensitive(httpTransport.isHeaderCacheCaseSensitive());
}
- retainableByteBufferPool = httpClient.getByteBufferPool().asRetainableByteBufferPool();
+ retainableByteBufferPool = httpClient.getRetainableByteBufferPool();
}
void receive()
@@ -169,7 +169,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
protected ByteBuffer getResponseBuffer()
{
- return networkBuffer == null ? null : networkBuffer.getBuffer();
+ return networkBuffer == null ? null : networkBuffer.getByteBuffer();
}
private void acquireNetworkBuffer()
@@ -222,7 +222,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
HttpClient client = getHttpDestination().getHttpClient();
upgradeBuffer = BufferUtil.allocate(networkBuffer.remaining(), client.isUseInputDirectByteBuffers());
BufferUtil.clearToFill(upgradeBuffer);
- BufferUtil.put(networkBuffer.getBuffer(), upgradeBuffer);
+ BufferUtil.put(networkBuffer.getByteBuffer(), upgradeBuffer);
BufferUtil.flipToFlush(upgradeBuffer, 0);
}
releaseNetworkBuffer();
@@ -245,7 +245,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
while (true)
{
if (LOG.isDebugEnabled())
- LOG.debug("Parsing {} in {}", BufferUtil.toDetailString(networkBuffer.getBuffer()), this);
+ LOG.debug("Parsing {} in {}", BufferUtil.toDetailString(networkBuffer.getByteBuffer()), this);
// Always parse even empty buffers to advance the parser.
if (parse())
{
@@ -269,7 +269,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
reacquireNetworkBuffer();
// The networkBuffer may have been reacquired.
- int read = endPoint.fill(networkBuffer.getBuffer());
+ int read = endPoint.fill(networkBuffer.getByteBuffer());
if (LOG.isDebugEnabled())
LOG.debug("Read {} bytes in {} from {} in {}", read, networkBuffer, endPoint, this);
@@ -309,7 +309,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
{
while (true)
{
- boolean handle = parser.parseNext(networkBuffer.getBuffer());
+ boolean handle = parser.parseNext(networkBuffer.getByteBuffer());
if (LOG.isDebugEnabled())
LOG.debug("Parse result={} on {}", handle, this);
Runnable action = getAndSetAction(null);
@@ -347,7 +347,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
if (getHttpChannel().isTunnel(method, status))
return true;
- if (networkBuffer.isEmpty())
+ if (!networkBuffer.hasRemaining())
return false;
if (!HttpStatus.isInformational(status))
@@ -359,7 +359,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
return false;
}
- if (networkBuffer.isEmpty())
+ if (!networkBuffer.hasRemaining())
return false;
}
}
diff --git a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpSenderOverHTTP.java b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpSenderOverHTTP.java
index b7ae70d47cb..b9bf13897ce 100644
--- a/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpSenderOverHTTP.java
+++ b/jetty-core/jetty-client/src/main/java/org/eclipse/jetty/client/transport/internal/HttpSenderOverHTTP.java
@@ -23,9 +23,10 @@ import org.eclipse.jetty.client.internal.HttpSender;
import org.eclipse.jetty.http.HttpGenerator;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
@@ -41,7 +42,7 @@ public class HttpSenderOverHTTP extends HttpSender
private final HttpGenerator generator = new HttpGenerator();
private HttpExchange exchange;
private MetaData.Request metaData;
- private ByteBuffer contentBuffer;
+ private ByteBuffer contentByteBuffer;
private boolean lastContent;
private Callback callback;
private boolean shutdown;
@@ -63,7 +64,7 @@ public class HttpSenderOverHTTP extends HttpSender
try
{
this.exchange = exchange;
- this.contentBuffer = contentBuffer;
+ this.contentByteBuffer = contentBuffer;
this.lastContent = lastContent;
this.callback = callback;
HttpRequest request = exchange.getRequest();
@@ -92,7 +93,7 @@ public class HttpSenderOverHTTP extends HttpSender
try
{
this.exchange = exchange;
- this.contentBuffer = contentBuffer;
+ this.contentByteBuffer = contentBuffer;
this.lastContent = lastContent;
this.callback = callback;
if (LOG.isDebugEnabled())
@@ -144,8 +145,8 @@ public class HttpSenderOverHTTP extends HttpSender
private class HeadersCallback extends IteratingCallback
{
- private ByteBuffer headerBuffer;
- private ByteBuffer chunkBuffer;
+ private RetainableByteBuffer headerBuffer;
+ private RetainableByteBuffer chunkBuffer;
private boolean generated;
private HeadersCallback()
@@ -157,52 +158,54 @@ public class HttpSenderOverHTTP extends HttpSender
protected Action process() throws Exception
{
HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient();
- ByteBufferPool byteBufferPool = httpClient.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = httpClient.getRetainableByteBufferPool();
boolean useDirectByteBuffers = httpClient.isUseOutputDirectByteBuffers();
while (true)
{
- HttpGenerator.Result result = generator.generateRequest(metaData, headerBuffer, chunkBuffer, contentBuffer, lastContent);
+ ByteBuffer headerByteBuffer = headerBuffer == null ? null : headerBuffer.getByteBuffer();
+ ByteBuffer chunkByteBuffer = chunkBuffer == null ? null : chunkBuffer.getByteBuffer();
+ HttpGenerator.Result result = generator.generateRequest(metaData, headerByteBuffer, chunkByteBuffer, contentByteBuffer, lastContent);
if (LOG.isDebugEnabled())
LOG.debug("Generated headers ({} bytes), chunk ({} bytes), content ({} bytes) - {}/{} for {}",
- headerBuffer == null ? -1 : headerBuffer.remaining(),
- chunkBuffer == null ? -1 : chunkBuffer.remaining(),
- contentBuffer == null ? -1 : contentBuffer.remaining(),
+ headerByteBuffer == null ? -1 : headerByteBuffer.remaining(),
+ chunkByteBuffer == null ? -1 : chunkByteBuffer.remaining(),
+ contentByteBuffer == null ? -1 : contentByteBuffer.remaining(),
result, generator, exchange.getRequest());
switch (result)
{
case NEED_HEADER:
{
- headerBuffer = byteBufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers);
+ headerBuffer = bufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers);
break;
}
case HEADER_OVERFLOW:
{
- httpClient.getByteBufferPool().release(headerBuffer);
+ headerBuffer.release();
headerBuffer = null;
throw new IllegalArgumentException("Request header too large");
}
case NEED_CHUNK:
{
- chunkBuffer = byteBufferPool.acquire(HttpGenerator.CHUNK_SIZE, useDirectByteBuffers);
+ chunkBuffer = bufferPool.acquire(HttpGenerator.CHUNK_SIZE, useDirectByteBuffers);
break;
}
case NEED_CHUNK_TRAILER:
{
- chunkBuffer = byteBufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers);
+ chunkBuffer = bufferPool.acquire(httpClient.getRequestBufferSize(), useDirectByteBuffers);
break;
}
case FLUSH:
{
EndPoint endPoint = getHttpChannel().getHttpConnection().getEndPoint();
- if (headerBuffer == null)
- headerBuffer = BufferUtil.EMPTY_BUFFER;
- if (chunkBuffer == null)
- chunkBuffer = BufferUtil.EMPTY_BUFFER;
- if (contentBuffer == null)
- contentBuffer = BufferUtil.EMPTY_BUFFER;
- long bytes = headerBuffer.remaining() + chunkBuffer.remaining() + contentBuffer.remaining();
+ if (headerByteBuffer == null)
+ headerByteBuffer = BufferUtil.EMPTY_BUFFER;
+ if (chunkByteBuffer == null)
+ chunkByteBuffer = BufferUtil.EMPTY_BUFFER;
+ if (contentByteBuffer == null)
+ contentByteBuffer = BufferUtil.EMPTY_BUFFER;
+ long bytes = headerByteBuffer.remaining() + chunkByteBuffer.remaining() + contentByteBuffer.remaining();
getHttpChannel().getHttpConnection().addBytesOut(bytes);
- endPoint.write(this, headerBuffer, chunkBuffer, contentBuffer);
+ endPoint.write(this, headerByteBuffer, chunkByteBuffer, contentByteBuffer);
generated = true;
return Action.SCHEDULED;
}
@@ -263,21 +266,19 @@ public class HttpSenderOverHTTP extends HttpSender
private void release()
{
- HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient();
- ByteBufferPool bufferPool = httpClient.getByteBufferPool();
- if (!BufferUtil.isTheEmptyBuffer(headerBuffer))
- bufferPool.release(headerBuffer);
+ if (headerBuffer != null)
+ headerBuffer.release();
headerBuffer = null;
- if (!BufferUtil.isTheEmptyBuffer(chunkBuffer))
- bufferPool.release(chunkBuffer);
+ if (chunkBuffer != null)
+ chunkBuffer.release();
chunkBuffer = null;
- contentBuffer = null;
+ contentByteBuffer = null;
}
}
private class ContentCallback extends IteratingCallback
{
- private ByteBuffer chunkBuffer;
+ private RetainableByteBuffer chunkBuffer;
public ContentCallback()
{
@@ -288,14 +289,15 @@ public class HttpSenderOverHTTP extends HttpSender
protected Action process() throws Exception
{
HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient();
- ByteBufferPool bufferPool = httpClient.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = httpClient.getRetainableByteBufferPool();
boolean useDirectByteBuffers = httpClient.isUseOutputDirectByteBuffers();
while (true)
{
- HttpGenerator.Result result = generator.generateRequest(null, null, chunkBuffer, contentBuffer, lastContent);
+ ByteBuffer chunkByteBuffer = chunkBuffer == null ? null : chunkBuffer.getByteBuffer();
+ HttpGenerator.Result result = generator.generateRequest(null, null, chunkByteBuffer, contentByteBuffer, lastContent);
if (LOG.isDebugEnabled())
LOG.debug("Generated content ({} bytes, last={}) - {}/{}",
- contentBuffer == null ? -1 : contentBuffer.remaining(),
+ contentByteBuffer == null ? -1 : contentByteBuffer.remaining(),
lastContent, result, generator);
switch (result)
{
@@ -312,10 +314,10 @@ public class HttpSenderOverHTTP extends HttpSender
case FLUSH:
{
EndPoint endPoint = getHttpChannel().getHttpConnection().getEndPoint();
- if (chunkBuffer != null)
- endPoint.write(this, chunkBuffer, contentBuffer);
+ if (chunkByteBuffer != null)
+ endPoint.write(this, chunkByteBuffer, contentByteBuffer);
else
- endPoint.write(this, contentBuffer);
+ endPoint.write(this, contentByteBuffer);
return Action.SCHEDULED;
}
case SHUTDOWN_OUT:
@@ -350,11 +352,10 @@ public class HttpSenderOverHTTP extends HttpSender
private void release()
{
- HttpClient httpClient = getHttpChannel().getHttpDestination().getHttpClient();
- ByteBufferPool bufferPool = httpClient.getByteBufferPool();
- bufferPool.release(chunkBuffer);
+ if (chunkBuffer != null)
+ chunkBuffer.release();
chunkBuffer = null;
- contentBuffer = null;
+ contentByteBuffer = null;
}
}
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
index 3083aaad235..c9824032702 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
@@ -27,9 +27,9 @@ import java.util.zip.GZIPOutputStream;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.Content;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.Callback;
@@ -242,9 +242,9 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
}
});
- ByteBufferPool pool = client.getByteBufferPool();
- assumeTrue(pool instanceof MappedByteBufferPool);
- MappedByteBufferPool bufferPool = (MappedByteBufferPool)pool;
+ RetainableByteBufferPool pool = client.getRetainableByteBufferPool();
+ assumeTrue(pool instanceof ArrayRetainableByteBufferPool);
+ ArrayRetainableByteBufferPool bufferPool = (ArrayRetainableByteBufferPool)pool;
ContentResponse response = client.newRequest("localhost", connector.getLocalPort())
.scheme(scenario.getScheme())
@@ -254,9 +254,9 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
assertEquals(HttpStatus.OK_200, response.getStatus());
assertArrayEquals(content, response.getContent());
- long directMemory = bufferPool.getMemory(true);
+ long directMemory = bufferPool.getDirectMemory();
assertThat(directMemory, lessThan((long)content.length));
- long heapMemory = bufferPool.getMemory(false);
+ long heapMemory = bufferPool.getHeapMemory();
assertThat(heapMemory, lessThan((long)content.length));
}
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
index 28374c541c3..74cd82f04e0 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientTLSTest.java
@@ -44,9 +44,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.io.ArrayByteBufferPool;
import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.Connection;
@@ -632,7 +630,7 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(connector.getRetainableByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected int networkFill(ByteBuffer input) throws IOException
@@ -666,12 +664,12 @@ public class HttpClientTLSTest
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
- return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory)
+ return new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), connectionFactory)
{
@Override
- protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
+ protected SslConnection newSslConnection(RetainableByteBufferPool bufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(bufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected int networkFill(ByteBuffer input) throws IOException
@@ -707,50 +705,6 @@ public class HttpClientTLSTest
assertEquals(0, clientBytes.get());
}
- protected class TestRetained extends ArrayRetainableByteBufferPool
- {
- private final ByteBufferPool _pool;
-
- public TestRetained(ByteBufferPool pool, int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
- {
- super(0, factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
- _pool = pool;
- }
-
- @Override
- protected ByteBuffer allocate(int capacity)
- {
- return _pool.acquire(capacity, false);
- }
-
- @Override
- protected ByteBuffer allocateDirect(int capacity)
- {
- return _pool.acquire(capacity, true);
- }
-
- @Override
- protected void removed(RetainableByteBuffer retainedBuffer)
- {
- _pool.release(retainedBuffer.getBuffer());
- }
-
- @Override
- public Pool poolFor(int capacity, boolean direct)
- {
- return super.poolFor(capacity, direct);
- }
- }
-
- private class TestByteBufferPool extends ArrayByteBufferPool
- {
- @Override
- protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
- {
- return new TestRetained(this, factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
- }
- }
-
@Test
public void testEncryptedInputBufferRepooling() throws Exception
{
@@ -759,9 +713,6 @@ public class HttpClientTLSTest
serverThreads.setName("server");
server = new Server(serverThreads);
- ArrayByteBufferPool byteBufferPool = new TestByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
- server.addBean(byteBufferPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
@@ -770,9 +721,8 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = connector.getBean(RetainableByteBufferPool.class);
- return new SslConnection(retainableByteBufferPool, byteBufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ RetainableByteBufferPool bufferPool = connector.getRetainableByteBufferPool();
+ return new SslConnection(bufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected int networkFill(ByteBuffer input) throws IOException
@@ -803,11 +753,12 @@ public class HttpClientTLSTest
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
- Pool bucket = ((TestRetained)retainableByteBufferPool).poolFor(16 * 1024 + 1, connector.getConnectionFactory(HttpConnectionFactory.class).isUseInputDirectByteBuffers());
+ ArrayRetainableByteBufferPool bufferPool = (ArrayRetainableByteBufferPool)server.getRetainableByteBufferPool();
+ Pool bucket = bufferPool.poolFor(16 * 1024 + 1, connector.getConnectionFactory(HttpConnectionFactory.class).isUseInputDirectByteBuffers());
assertEquals(1, bucket.size());
assertEquals(1, bucket.getIdleCount());
- long count = ssl.isDirectBuffersForDecryption() ? byteBufferPool.getDirectByteBufferCount() : byteBufferPool.getHeapByteBufferCount();
+ long count = ssl.isDirectBuffersForDecryption() ? bufferPool.getDirectByteBufferCount() : bufferPool.getHeapByteBufferCount();
assertEquals(1, count);
}
@@ -817,26 +768,28 @@ public class HttpClientTLSTest
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
- server = new Server(serverThreads);
- List leakedBuffers = new CopyOnWriteArrayList<>();
- ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
+ List leakedBuffers = new CopyOnWriteArrayList<>();
+ RetainableByteBufferPool bufferPool = new RetainableByteBufferPool.Wrapper(new ArrayRetainableByteBufferPool())
{
@Override
- public ByteBuffer acquire(int size, boolean direct)
+ public RetainableByteBuffer acquire(int size, boolean direct)
{
- ByteBuffer acquired = super.acquire(size, direct);
- leakedBuffers.add(acquired);
- return acquired;
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- leakedBuffers.remove(buffer);
- super.release(buffer);
+ RetainableByteBuffer.Wrapper buffer = new RetainableByteBuffer.Wrapper(super.acquire(size, direct))
+ {
+ @Override
+ public boolean release()
+ {
+ boolean released = super.release();
+ if (released)
+ leakedBuffers.remove(this);
+ return released;
+ }
+ };
+ leakedBuffers.add(buffer);
+ return buffer;
}
};
- server.addBean(byteBufferPool);
+ server = new Server(serverThreads, null, bufferPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
@@ -845,9 +798,8 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = connector.getBean(RetainableByteBufferPool.class);
- return new SslConnection(retainableByteBufferPool, byteBufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ RetainableByteBufferPool bufferPool = connector.getRetainableByteBufferPool();
+ return new SslConnection(bufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected boolean networkFlush(ByteBuffer output) throws IOException
@@ -875,7 +827,7 @@ public class HttpClientTLSTest
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
- byteBufferPool.asRetainableByteBufferPool().clear();
+ bufferPool.clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
@@ -886,26 +838,28 @@ public class HttpClientTLSTest
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
- server = new Server(serverThreads);
- List leakedBuffers = new CopyOnWriteArrayList<>();
- ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
+ List leakedBuffers = new CopyOnWriteArrayList<>();
+ RetainableByteBufferPool bufferPool = new RetainableByteBufferPool.Wrapper(new ArrayRetainableByteBufferPool())
{
@Override
- public ByteBuffer acquire(int size, boolean direct)
+ public RetainableByteBuffer acquire(int size, boolean direct)
{
- ByteBuffer acquired = super.acquire(size, direct);
- leakedBuffers.add(acquired);
- return acquired;
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- leakedBuffers.remove(buffer);
- super.release(buffer);
+ RetainableByteBuffer.Wrapper buffer = new RetainableByteBuffer.Wrapper(super.acquire(size, direct))
+ {
+ @Override
+ public boolean release()
+ {
+ boolean released = super.release();
+ if (released)
+ leakedBuffers.remove(this);
+ return released;
+ }
+ };
+ leakedBuffers.add(buffer);
+ return buffer;
}
};
- server.addBean(byteBufferPool);
+ server = new Server(serverThreads, null, bufferPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
@@ -915,9 +869,8 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = connector.getBean(RetainableByteBufferPool.class);
- return new SslConnection(retainableByteBufferPool, byteBufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ RetainableByteBufferPool bufferPool = connector.getRetainableByteBufferPool();
+ return new SslConnection(bufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected boolean networkFlush(ByteBuffer output) throws IOException
@@ -934,7 +887,7 @@ public class HttpClientTLSTest
server.setHandler(new EmptyServerHandler()
{
@Override
- protected void service(Request request, Response response) throws Throwable
+ protected void service(Request request, Response response)
{
failFlush.set(true);
EndPoint endPoint = request.getConnectionMetaData().getConnection().getEndPoint();
@@ -959,7 +912,7 @@ public class HttpClientTLSTest
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
- byteBufferPool.asRetainableByteBufferPool().clear();
+ bufferPool.clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
@@ -970,26 +923,28 @@ public class HttpClientTLSTest
SslContextFactory.Server serverTLSFactory = createServerSslContextFactory();
QueuedThreadPool serverThreads = new QueuedThreadPool();
serverThreads.setName("server");
- server = new Server(serverThreads);
- List leakedBuffers = new CopyOnWriteArrayList<>();
- ArrayByteBufferPool byteBufferPool = new ArrayByteBufferPool()
+ List leakedBuffers = new CopyOnWriteArrayList<>();
+ RetainableByteBufferPool bufferPool = new RetainableByteBufferPool.Wrapper(new ArrayRetainableByteBufferPool())
{
@Override
- public ByteBuffer acquire(int size, boolean direct)
+ public RetainableByteBuffer acquire(int size, boolean direct)
{
- ByteBuffer acquired = super.acquire(size, direct);
- leakedBuffers.add(acquired);
- return acquired;
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- leakedBuffers.remove(buffer);
- super.release(buffer);
+ RetainableByteBuffer.Wrapper buffer = new RetainableByteBuffer.Wrapper(super.acquire(size, direct))
+ {
+ @Override
+ public boolean release()
+ {
+ boolean released = super.release();
+ if (released)
+ leakedBuffers.remove(this);
+ return released;
+ }
+ };
+ leakedBuffers.add(buffer);
+ return buffer;
}
};
- server.addBean(byteBufferPool);
+ server = new Server(serverThreads, null, bufferPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new SecureRequestCustomizer());
HttpConnectionFactory http = new HttpConnectionFactory(httpConfig);
@@ -999,9 +954,8 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- RetainableByteBufferPool retainableByteBufferPool = connector.getBean(RetainableByteBufferPool.class);
- return new SslConnection(retainableByteBufferPool, byteBufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ RetainableByteBufferPool bufferPool = connector.getRetainableByteBufferPool();
+ return new SslConnection(bufferPool, connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected boolean networkFlush(ByteBuffer output) throws IOException
@@ -1018,7 +972,7 @@ public class HttpClientTLSTest
server.setHandler(new EmptyServerHandler()
{
@Override
- protected void service(Request request, Response response) throws Throwable
+ protected void service(Request request, Response response)
{
failFlush.set(true);
EndPoint endPoint = request.getConnectionMetaData().getConnection().getEndPoint();
@@ -1043,7 +997,7 @@ public class HttpClientTLSTest
assertThrows(Exception.class, () -> client.newRequest("localhost", connector.getLocalPort()).scheme(HttpScheme.HTTPS.asString()).send());
- byteBufferPool.asRetainableByteBufferPool().clear();
+ bufferPool.clear();
await().atMost(5, TimeUnit.SECONDS).until(() -> leakedBuffers, is(empty()));
}
@@ -1063,7 +1017,7 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(connector.getRetainableByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected int networkFill(ByteBuffer input) throws IOException
@@ -1098,12 +1052,12 @@ public class HttpClientTLSTest
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
- return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory)
+ return new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), connectionFactory)
{
@Override
- protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
+ protected SslConnection newSslConnection(RetainableByteBufferPool bufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(bufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected int networkFill(ByteBuffer input) throws IOException
@@ -1160,12 +1114,12 @@ public class HttpClientTLSTest
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
- return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory)
+ return new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), connectionFactory)
{
@Override
- protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
+ protected SslConnection newSslConnection(RetainableByteBufferPool bufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(bufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException
@@ -1204,7 +1158,7 @@ public class HttpClientTLSTest
@Override
protected SslConnection newSslConnection(Connector connector, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(connector.getByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(connector.getRetainableByteBufferPool(), connector.getExecutor(), endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult unwrap(SSLEngine sslEngine, ByteBuffer input, ByteBuffer output) throws SSLException
@@ -1240,12 +1194,12 @@ public class HttpClientTLSTest
{
if (sslContextFactory == null)
sslContextFactory = getSslContextFactory();
- return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory)
+ return new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), connectionFactory)
{
@Override
- protected SslConnection newSslConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
+ protected SslConnection newSslConnection(RetainableByteBufferPool bufferPool, Executor executor, EndPoint endPoint, SSLEngine engine)
{
- return new SslConnection(byteBufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
+ return new SslConnection(bufferPool, executor, endPoint, engine, isDirectBuffersForEncryption(), isDirectBuffersForDecryption())
{
@Override
protected SSLEngineResult wrap(SSLEngine sslEngine, ByteBuffer[] input, ByteBuffer output) throws SSLException
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java
index b519f1af452..bfbd8a1e8a1 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/ssl/SslConnectionTest.java
@@ -19,10 +19,10 @@ import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLHandshakeException;
import org.eclipse.jetty.io.AbstractConnection;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.ByteArrayEndPoint;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.ssl.SslConnection;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.BufferUtil;
@@ -43,13 +43,13 @@ public class SslConnectionTest
sslContextFactory.setKeyStorePassword("storepwd");
sslContextFactory.start();
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.start();
ByteArrayEndPoint endPoint = new ByteArrayEndPoint();
SSLEngine sslEngine = sslContextFactory.newSSLEngine();
sslEngine.setUseClientMode(false);
- SslConnection sslConnection = new SslConnection(byteBufferPool, threadPool, endPoint, sslEngine);
+ SslConnection sslConnection = new SslConnection(bufferPool, threadPool, endPoint, sslEngine);
EndPoint sslEndPoint = sslConnection.getDecryptedEndPoint();
sslEndPoint.setConnection(new AbstractConnection(sslEndPoint, threadPool)
{
diff --git a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartRequestContentTest.java b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartRequestContentTest.java
index c43a57d58c2..198d054346f 100644
--- a/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartRequestContentTest.java
+++ b/jetty-core/jetty-client/src/test/java/org/eclipse/jetty/client/util/MultiPartRequestContentTest.java
@@ -283,7 +283,7 @@ public class MultiPartRequestContentTest extends AbstractHttpClientServerTest
});
MultiPartRequestContent multiPart = new MultiPartRequestContent();
- PathRequestContent content = new PathRequestContent(contentType, tmpPath, client.getByteBufferPool().asRetainableByteBufferPool());
+ PathRequestContent content = new PathRequestContent(contentType, tmpPath, client.getRetainableByteBufferPool());
content.setUseDirectByteBuffers(client.isUseOutputDirectByteBuffers());
multiPart.addPart(new MultiPart.ContentSourcePart(name, tmpPath.getFileName().toString(), null, content));
multiPart.close();
diff --git a/jetty-core/jetty-deploy/src/test/resources/jetty.xml b/jetty-core/jetty-deploy/src/test/resources/jetty.xml
index 5afa3f4249a..48fb93c25f0 100644
--- a/jetty-core/jetty-deploy/src/test/resources/jetty.xml
+++ b/jetty-core/jetty-deploy/src/test/resources/jetty.xml
@@ -42,8 +42,8 @@
-
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpChannelOverFCGI.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpChannelOverFCGI.java
index f45e1b762e3..13276396f49 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpChannelOverFCGI.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpChannelOverFCGI.java
@@ -21,12 +21,13 @@ import org.eclipse.jetty.client.internal.HttpExchange;
import org.eclipse.jetty.client.internal.HttpReceiver;
import org.eclipse.jetty.client.internal.HttpSender;
import org.eclipse.jetty.fcgi.generator.Flusher;
-import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.IdleTimeout;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -161,9 +162,9 @@ public class HttpChannelOverFCGI extends HttpChannel
release();
}
- protected void flush(Generator.Result... results)
+ protected void flush(RetainableByteBufferPool.Accumulator accumulator, Callback callback)
{
- flusher.flush(results);
+ flusher.flush(accumulator, callback);
}
void receive()
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpConnectionOverFCGI.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpConnectionOverFCGI.java
index d91360e1505..7fe15be9075 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpConnectionOverFCGI.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpConnectionOverFCGI.java
@@ -81,7 +81,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
this.parser = new ClientParser(new ResponseListener());
requests.addLast(0);
HttpClient client = destination.getHttpClient();
- this.networkByteBufferPool = client.getByteBufferPool().asRetainableByteBufferPool();
+ this.networkByteBufferPool = client.getRetainableByteBufferPool();
}
public HttpDestination getHttpDestination()
@@ -161,14 +161,14 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements IConne
{
while (true)
{
- if (parse(networkBuffer.getBuffer()))
+ if (parse(networkBuffer.getByteBuffer()))
return false;
if (networkBuffer.isRetained())
reacquireNetworkBuffer();
// The networkBuffer may have been reacquired.
- int read = endPoint.fill(networkBuffer.getBuffer());
+ int read = endPoint.fill(networkBuffer.getByteBuffer());
if (LOG.isDebugEnabled())
LOG.debug("Read {} bytes from {}", read, endPoint);
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpSenderOverFCGI.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpSenderOverFCGI.java
index 1ebf7391793..fd5fa644162 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpSenderOverFCGI.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/transport/internal/HttpSenderOverFCGI.java
@@ -26,10 +26,10 @@ import org.eclipse.jetty.client.internal.HttpSender;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.fcgi.client.transport.HttpClientTransportOverFCGI;
import org.eclipse.jetty.fcgi.generator.ClientGenerator;
-import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Jetty;
import org.eclipse.jetty.util.StringUtil;
@@ -42,7 +42,7 @@ public class HttpSenderOverFCGI extends HttpSender
{
super(channel);
HttpClient httpClient = channel.getHttpDestination().getHttpClient();
- this.generator = new ClientGenerator(httpClient.getByteBufferPool(), httpClient.isUseOutputDirectByteBuffers());
+ this.generator = new ClientGenerator(httpClient.getRetainableByteBufferPool(), httpClient.isUseOutputDirectByteBuffers());
}
@Override
@@ -98,18 +98,18 @@ public class HttpSenderOverFCGI extends HttpSender
HttpClientTransportOverFCGI transport = (HttpClientTransportOverFCGI)getHttpChannel().getHttpDestination().getHttpClient().getTransport();
transport.customize(request, fcgiHeaders);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
int id = getHttpChannel().getRequest();
if (contentBuffer.hasRemaining() || lastContent)
{
- Generator.Result headersResult = generator.generateRequestHeaders(id, fcgiHeaders, Callback.NOOP);
- Generator.Result contentResult = generator.generateRequestContent(id, contentBuffer, lastContent, callback);
- getHttpChannel().flush(headersResult, contentResult);
+ generator.generateRequestHeaders(accumulator, id, fcgiHeaders);
+ generator.generateRequestContent(accumulator, id, contentBuffer, lastContent);
}
else
{
- Generator.Result headersResult = generator.generateRequestHeaders(id, fcgiHeaders, callback);
- getHttpChannel().flush(headersResult);
+ generator.generateRequestHeaders(accumulator, id, fcgiHeaders);
}
+ getHttpChannel().flush(accumulator, callback);
}
@Override
@@ -117,9 +117,10 @@ public class HttpSenderOverFCGI extends HttpSender
{
if (contentBuffer.hasRemaining() || lastContent)
{
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
int request = getHttpChannel().getRequest();
- Generator.Result result = generator.generateRequestContent(request, contentBuffer, lastContent, callback);
- getHttpChannel().flush(result);
+ generator.generateRequestContent(accumulator, request, contentBuffer, lastContent);
+ getHttpChannel().flush(accumulator, callback);
}
else
{
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java
index 205f1329468..7688c3fff65 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ClientGenerator.java
@@ -22,9 +22,9 @@ import java.util.List;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
public class ClientGenerator extends Generator
{
@@ -33,17 +33,17 @@ public class ClientGenerator extends Generator
// 0x7F_FF - 4 (the 4 is to make room for the name (or value) length).
public static final int MAX_PARAM_LENGTH = 0x7F_FF - 4;
- public ClientGenerator(ByteBufferPool byteBufferPool)
+ public ClientGenerator(RetainableByteBufferPool bufferPool)
{
- this(byteBufferPool, true);
+ this(bufferPool, true);
}
- public ClientGenerator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers)
+ public ClientGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
- super(byteBufferPool, useDirectByteBuffers);
+ super(bufferPool, useDirectByteBuffers);
}
- public Result generateRequestHeaders(int request, HttpFields fields, Callback callback)
+ public void generateRequestHeaders(RetainableByteBufferPool.Accumulator accumulator, int request, HttpFields fields)
{
request &= 0xFF_FF;
@@ -79,30 +79,31 @@ public class ClientGenerator extends Generator
// One FCGI_BEGIN_REQUEST + N FCGI_PARAMS + one last FCGI_PARAMS
- ByteBuffer beginRequestBuffer = acquire(16);
- BufferUtil.clearToFill(beginRequestBuffer);
- Result result = new Result(getByteBufferPool(), callback);
- result = result.append(beginRequestBuffer, true);
+ RetainableByteBuffer beginBuffer = getRetainableByteBufferPool().acquire(16, isUseDirectByteBuffers());
+ accumulator.append(beginBuffer);
+ ByteBuffer beginByteBuffer = beginBuffer.getByteBuffer();
+ BufferUtil.clearToFill(beginByteBuffer);
// Generate the FCGI_BEGIN_REQUEST frame
- beginRequestBuffer.putInt(0x01_01_00_00 + request);
- beginRequestBuffer.putInt(0x00_08_00_00);
+ beginByteBuffer.putInt(0x01_01_00_00 + request);
+ beginByteBuffer.putInt(0x00_08_00_00);
// Hardcode RESPONDER role and KEEP_ALIVE flag
- beginRequestBuffer.putLong(0x00_01_01_00_00_00_00_00L);
- BufferUtil.flipToFlush(beginRequestBuffer, 0);
+ beginByteBuffer.putLong(0x00_01_01_00_00_00_00_00L);
+ BufferUtil.flipToFlush(beginByteBuffer, 0);
int index = 0;
while (fieldsLength > 0)
{
int capacity = 8 + Math.min(maxCapacity, fieldsLength);
- ByteBuffer buffer = acquire(capacity);
- BufferUtil.clearToFill(buffer);
- result = result.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(capacity, isUseDirectByteBuffers());
+ accumulator.append(buffer);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
// Generate the FCGI_PARAMS frame
- buffer.putInt(0x01_04_00_00 + request);
- buffer.putShort((short)0);
- buffer.putShort((short)0);
+ byteBuffer.putInt(0x01_04_00_00 + request);
+ byteBuffer.putShort((short)0);
+ byteBuffer.putShort((short)0);
capacity -= 8;
int length = 0;
@@ -117,10 +118,10 @@ public class ClientGenerator extends Generator
if (required > capacity)
break;
- putParamLength(buffer, nameLength);
- putParamLength(buffer, valueLength);
- buffer.put(nameBytes);
- buffer.put(valueBytes);
+ putParamLength(byteBuffer, nameLength);
+ putParamLength(byteBuffer, valueLength);
+ byteBuffer.put(nameBytes);
+ byteBuffer.put(valueBytes);
length += required;
fieldsLength -= required;
@@ -128,20 +129,19 @@ public class ClientGenerator extends Generator
index += 2;
}
- buffer.putShort(4, (short)length);
- BufferUtil.flipToFlush(buffer, 0);
+ byteBuffer.putShort(4, (short)length);
+ BufferUtil.flipToFlush(byteBuffer, 0);
}
- ByteBuffer lastParamsBuffer = acquire(8);
- BufferUtil.clearToFill(lastParamsBuffer);
- result = result.append(lastParamsBuffer, true);
+ RetainableByteBuffer lastBuffer = getRetainableByteBufferPool().acquire(8, isUseDirectByteBuffers());
+ accumulator.append(lastBuffer);
+ ByteBuffer lastByteBuffer = lastBuffer.getByteBuffer();
+ BufferUtil.clearToFill(lastByteBuffer);
// Generate the last FCGI_PARAMS frame
- lastParamsBuffer.putInt(0x01_04_00_00 + request);
- lastParamsBuffer.putInt(0x00_00_00_00);
- BufferUtil.flipToFlush(lastParamsBuffer, 0);
-
- return result;
+ lastByteBuffer.putInt(0x01_04_00_00 + request);
+ lastByteBuffer.putInt(0x00_00_00_00);
+ BufferUtil.flipToFlush(lastByteBuffer, 0);
}
private int putParamLength(ByteBuffer buffer, int length)
@@ -159,8 +159,8 @@ public class ClientGenerator extends Generator
return length > 127 ? 4 : 1;
}
- public Result generateRequestContent(int request, ByteBuffer content, boolean lastContent, Callback callback)
+ public void generateRequestContent(RetainableByteBufferPool.Accumulator accumulator, int request, ByteBuffer content, boolean lastContent)
{
- return generateContent(request, content, false, lastContent, callback, FCGI.FrameType.STDIN);
+ generateContent(accumulator, request, content, lastContent, FCGI.FrameType.STDIN);
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
index 49b2865f3a3..58ebcb0e74d 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Flusher.java
@@ -15,9 +15,12 @@ package org.eclipse.jetty.fcgi.generator;
import java.nio.ByteBuffer;
import java.util.ArrayDeque;
+import java.util.List;
import java.util.Queue;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.thread.AutoLock;
import org.slf4j.Logger;
@@ -28,7 +31,7 @@ public class Flusher
private static final Logger LOG = LoggerFactory.getLogger(Flusher.class);
private final AutoLock lock = new AutoLock();
- private final Queue queue = new ArrayDeque<>();
+ private final Queue queue = new ArrayDeque<>();
private final IteratingCallback flushCallback = new FlushCallback();
private final EndPoint endPoint;
@@ -37,24 +40,21 @@ public class Flusher
this.endPoint = endPoint;
}
- public void flush(Generator.Result... results)
+ public void flush(RetainableByteBufferPool.Accumulator accumulator, Callback callback)
{
- for (Generator.Result result : results)
- {
- offer(result);
- }
+ offer(new Entry(accumulator, callback));
flushCallback.iterate();
}
- private void offer(Generator.Result result)
+ private void offer(Entry entry)
{
try (AutoLock ignored = lock.lock())
{
- queue.offer(result);
+ queue.offer(entry);
}
}
- private Generator.Result poll()
+ private Entry poll()
{
try (AutoLock ignored = lock.lock())
{
@@ -64,35 +64,32 @@ public class Flusher
public void shutdown()
{
- flush(new ShutdownResult());
+ flush(null, Callback.from(() ->
+ {
+ if (LOG.isDebugEnabled())
+ LOG.debug("Shutting down {}", endPoint);
+ endPoint.shutdownOutput();
+ }));
}
private class FlushCallback extends IteratingCallback
{
- private Generator.Result active;
+ private Entry active;
@Override
protected Action process() throws Exception
{
// Look if other writes are needed.
- Generator.Result result = poll();
- if (result == null)
+ Entry entry = poll();
+ if (entry == null)
{
// No more writes to do, return.
return Action.IDLE;
}
- // Attempt to gather another result.
- // Most often there is another result in the
- // queue so this is a real optimization because
- // it sends both results in just one TCP packet.
- Generator.Result other = poll();
- if (other != null)
- result = result.join(other);
-
- active = result;
- ByteBuffer[] buffers = result.getByteBuffers();
- endPoint.write(this, buffers);
+ active = entry;
+ List buffers = entry.accumulator.getByteBuffers();
+ endPoint.write(this, buffers.toArray(ByteBuffer[]::new));
return Action.SCHEDULED;
}
@@ -121,38 +118,30 @@ public class Flusher
while (true)
{
- Generator.Result result = poll();
- if (result == null)
+ Entry entry = poll();
+ if (entry == null)
break;
- result.failed(x);
+ entry.failed(x);
}
}
}
- private class ShutdownResult extends Generator.Result
+ private record Entry(RetainableByteBufferPool.Accumulator accumulator, Callback callback) implements Callback
{
- private ShutdownResult()
- {
- super(null, null);
- }
-
@Override
public void succeeded()
{
- shutdown();
+ if (accumulator != null)
+ accumulator.release();
+ callback.succeeded();
}
@Override
public void failed(Throwable x)
{
- shutdown();
- }
-
- private void shutdown()
- {
- if (LOG.isDebugEnabled())
- LOG.debug("Shutting down {}", endPoint);
- endPoint.shutdownOutput();
+ if (accumulator != null)
+ accumulator.release();
+ callback.failed(x);
}
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
index 72e5ae2d513..9031b2c8eed 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/Generator.java
@@ -14,150 +14,69 @@
package org.eclipse.jetty.fcgi.generator;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
import org.eclipse.jetty.fcgi.FCGI;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
public class Generator
{
public static final int MAX_CONTENT_LENGTH = 0xFF_FF;
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final boolean useDirectByteBuffers;
- public Generator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers)
+ public Generator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
this.useDirectByteBuffers = useDirectByteBuffers;
}
- ByteBufferPool getByteBufferPool()
+ public RetainableByteBufferPool getRetainableByteBufferPool()
{
- return byteBufferPool;
+ return bufferPool;
}
- ByteBuffer acquire(int capacity)
+ public boolean isUseDirectByteBuffers()
{
- return byteBufferPool.acquire(capacity, useDirectByteBuffers);
+ return useDirectByteBuffers;
}
- protected Result generateContent(int id, ByteBuffer content, boolean recycle, boolean lastContent, Callback callback, FCGI.FrameType frameType)
+ protected void generateContent(RetainableByteBufferPool.Accumulator accumulator, int id, ByteBuffer content, boolean lastContent, FCGI.FrameType frameType)
{
id &= 0xFF_FF;
int contentLength = content == null ? 0 : content.remaining();
- Result result = new Result(byteBufferPool, callback);
while (contentLength > 0 || lastContent)
{
- ByteBuffer buffer = acquire(8);
- BufferUtil.clearToFill(buffer);
- result = result.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(8, isUseDirectByteBuffers());
+ accumulator.append(buffer);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
- // Generate the frame header
- buffer.put((byte)0x01);
- buffer.put((byte)frameType.code);
- buffer.putShort((short)id);
+ // Generate the frame header.
+ byteBuffer.put((byte)0x01);
+ byteBuffer.put((byte)frameType.code);
+ byteBuffer.putShort((short)id);
int length = Math.min(MAX_CONTENT_LENGTH, contentLength);
- buffer.putShort((short)length);
- buffer.putShort((short)0);
- BufferUtil.flipToFlush(buffer, 0);
+ byteBuffer.putShort((short)length);
+ byteBuffer.putShort((short)0);
+ BufferUtil.flipToFlush(byteBuffer, 0);
if (contentLength == 0)
break;
- // Slice the content to avoid copying
+ // Slice the content to avoid copying.
int limit = content.limit();
content.limit(content.position() + length);
ByteBuffer slice = content.slice();
- // Don't recycle the slice
- result = result.append(slice, false);
+ // Don't recycle the slice.
+ accumulator.append(RetainableByteBuffer.wrap(slice));
content.position(content.limit());
content.limit(limit);
contentLength -= length;
- // Recycle the content buffer if needed
- if (recycle && contentLength == 0)
- result = result.append(content, true);
- }
-
- return result;
- }
-
- // TODO: rewrite this class in light of ByteBufferPool.Lease.
- public static class Result implements Callback
- {
- private final List callbacks = new ArrayList<>(2);
- private final List buffers = new ArrayList<>(8);
- private final List recycles = new ArrayList<>(8);
- private final ByteBufferPool byteBufferPool;
-
- public Result(ByteBufferPool byteBufferPool, Callback callback)
- {
- this.byteBufferPool = byteBufferPool;
- this.callbacks.add(callback);
- }
-
- public Result append(ByteBuffer buffer, boolean recycle)
- {
- if (buffer != null)
- {
- buffers.add(buffer);
- recycles.add(recycle);
- }
- return this;
- }
-
- public Result join(Result that)
- {
- callbacks.addAll(that.callbacks);
- buffers.addAll(that.buffers);
- recycles.addAll(that.recycles);
- return this;
- }
-
- public ByteBuffer[] getByteBuffers()
- {
- return buffers.toArray(new ByteBuffer[0]);
- }
-
- @Override
- @SuppressWarnings("ForLoopReplaceableByForEach")
- public void succeeded()
- {
- recycle();
- for (int i = 0; i < callbacks.size(); ++i)
- {
- Callback callback = callbacks.get(i);
- if (callback != null)
- callback.succeeded();
- }
- }
-
- @Override
- @SuppressWarnings("ForLoopReplaceableByForEach")
- public void failed(Throwable x)
- {
- recycle();
- for (int i = 0; i < callbacks.size(); ++i)
- {
- Callback callback = callbacks.get(i);
- if (callback != null)
- callback.failed(x);
- }
- }
-
- protected void recycle()
- {
- for (int i = 0; i < buffers.size(); ++i)
- {
- ByteBuffer buffer = buffers.get(i);
- if (recycles.get(i))
- byteBufferPool.release(buffer);
- }
}
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
index cd75698f92c..de752e0335f 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/main/java/org/eclipse/jetty/fcgi/generator/ServerGenerator.java
@@ -23,9 +23,9 @@ import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpStatus;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.Callback;
public class ServerGenerator extends Generator
{
@@ -35,18 +35,18 @@ public class ServerGenerator extends Generator
private final boolean sendStatus200;
- public ServerGenerator(ByteBufferPool byteBufferPool)
+ public ServerGenerator(RetainableByteBufferPool bufferPool)
{
- this(byteBufferPool, true, true);
+ this(bufferPool, true, true);
}
- public ServerGenerator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers, boolean sendStatus200)
+ public ServerGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers, boolean sendStatus200)
{
- super(byteBufferPool, useDirectByteBuffers);
+ super(bufferPool, useDirectByteBuffers);
this.sendStatus200 = sendStatus200;
}
- public Result generateResponseHeaders(int request, int code, String reason, HttpFields fields, Callback callback)
+ public void generateResponseHeaders(RetainableByteBufferPool.Accumulator accumulator, int request, int code, String reason, HttpFields fields)
{
request &= 0xFF_FF;
@@ -83,50 +83,48 @@ public class ServerGenerator extends Generator
// End of headers
length += EOL.length;
- ByteBuffer buffer = acquire(length);
- BufferUtil.clearToFill(buffer);
+ ByteBuffer byteBuffer = BufferUtil.allocate(length, isUseDirectByteBuffers());
+ BufferUtil.clearToFill(byteBuffer);
for (int i = 0; i < bytes.size(); i += 2)
{
- buffer.put(bytes.get(i)).put(COLON).put(bytes.get(i + 1)).put(EOL);
+ byteBuffer.put(bytes.get(i)).put(COLON).put(bytes.get(i + 1)).put(EOL);
}
- buffer.put(EOL);
+ byteBuffer.put(EOL);
- BufferUtil.flipToFlush(buffer, 0);
+ BufferUtil.flipToFlush(byteBuffer, 0);
- return generateContent(request, buffer, true, false, callback, FCGI.FrameType.STDOUT);
+ generateContent(accumulator, request, byteBuffer, false, FCGI.FrameType.STDOUT);
}
- public Result generateResponseContent(int request, ByteBuffer content, boolean lastContent, boolean aborted, Callback callback)
+ public void generateResponseContent(RetainableByteBufferPool.Accumulator accumulator, int request, ByteBuffer content, boolean lastContent, boolean aborted)
{
if (aborted)
{
- Result result = new Result(getByteBufferPool(), callback);
if (lastContent)
- result.append(generateEndRequest(request, true), true);
+ accumulator.append(generateEndRequest(request, true));
else
- result.append(BufferUtil.EMPTY_BUFFER, false);
- return result;
+ accumulator.append(RetainableByteBuffer.wrap(BufferUtil.EMPTY_BUFFER));
}
else
{
- Result result = generateContent(request, content, false, lastContent, callback, FCGI.FrameType.STDOUT);
+ generateContent(accumulator, request, content, lastContent, FCGI.FrameType.STDOUT);
if (lastContent)
- result.append(generateEndRequest(request, false), true);
- return result;
+ accumulator.append(generateEndRequest(request, false));
}
}
- private ByteBuffer generateEndRequest(int request, boolean aborted)
+ private RetainableByteBuffer generateEndRequest(int request, boolean aborted)
{
request &= 0xFF_FF;
- ByteBuffer endRequestBuffer = acquire(16);
- BufferUtil.clearToFill(endRequestBuffer);
- endRequestBuffer.putInt(0x01_03_00_00 + request);
- endRequestBuffer.putInt(0x00_08_00_00);
- endRequestBuffer.putInt(aborted ? 1 : 0);
- endRequestBuffer.putInt(0);
- BufferUtil.flipToFlush(endRequestBuffer, 0);
+ RetainableByteBuffer endRequestBuffer = getRetainableByteBufferPool().acquire(16, isUseDirectByteBuffers());
+ ByteBuffer byteBuffer = endRequestBuffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.putInt(0x01_03_00_00 + request);
+ byteBuffer.putInt(0x00_08_00_00);
+ byteBuffer.putInt(aborted ? 1 : 0);
+ byteBuffer.putInt(0);
+ BufferUtil.flipToFlush(byteBuffer, 0);
return endRequestBuffer;
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java
index 27a65fd10ad..4ffe773ba97 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/generator/ClientGeneratorTest.java
@@ -21,8 +21,8 @@ import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.fcgi.parser.ServerParser;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -31,50 +31,51 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
public class ClientGeneratorTest
{
@Test
- public void testGenerateRequestHeaders() throws Exception
+ public void testGenerateRequestHeaders()
{
HttpFields.Mutable fields = HttpFields.build();
// Short name, short value
final String shortShortName = "REQUEST_METHOD";
- final String shortShortValue = "GET";
+ String shortShortValue = "GET";
fields.put(new HttpField(shortShortName, shortShortValue));
// Short name, long value
final String shortLongName = "REQUEST_URI";
// Be sure it's longer than 127 chars to test the large value
- final String shortLongValue = "/api/0.6/map?bbox=-64.217736,-31.456810,-64.187736,-31.432322,filler=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
+ String shortLongValue = "/api/0.6/map?bbox=-64.217736,-31.456810,-64.187736,-31.432322,filler=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
fields.put(new HttpField(shortLongName, shortLongValue));
// Long name, short value
// Be sure it's longer than 127 chars to test the large name
final String longShortName = "FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210FEDCBA9876543210";
- final String longShortValue = "api.openstreetmap.org";
+ String longShortValue = "api.openstreetmap.org";
fields.put(new HttpField(longShortName, longShortValue));
// Long name, long value
char[] chars = new char[ClientGenerator.MAX_PARAM_LENGTH];
Arrays.fill(chars, 'z');
- final String longLongName = new String(chars);
- final String longLongValue = new String(chars);
+ String longLongName = new String(chars);
+ String longLongValue = new String(chars);
fields.put(new HttpField(longLongName, longLongValue));
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ClientGenerator generator = new ClientGenerator(byteBufferPool);
- final int id = 13;
- Generator.Result result = generator.generateRequestHeaders(id, fields, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ClientGenerator generator = new ClientGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ int id = 13;
+ generator.generateRequestHeaders(accumulator, id, fields);
// Use the fundamental theorem of arithmetic to test the results.
// This way we know onHeader() has been called the right number of
// times with the right arguments, and so onHeaders().
- final int[] primes = new int[]{2, 3, 5, 7, 11};
+ int[] primes = new int[]{2, 3, 5, 7, 11};
int value = 1;
for (int prime : primes)
{
value *= prime;
}
- final AtomicInteger params = new AtomicInteger(1);
+ AtomicInteger params = new AtomicInteger(1);
ServerParser parser = new ServerParser(new ServerParser.Listener.Adapter()
{
@Override
@@ -83,23 +84,27 @@ public class ClientGeneratorTest
assertEquals(id, request);
switch (field.getName())
{
- case shortShortName:
+ case shortShortName ->
+ {
assertEquals(shortShortValue, field.getValue());
params.set(params.get() * primes[0]);
- break;
- case shortLongName:
+ }
+ case shortLongName ->
+ {
assertEquals(shortLongValue, field.getValue());
params.set(params.get() * primes[1]);
- break;
- case longShortName:
+ }
+ case longShortName ->
+ {
assertEquals(longShortValue, field.getValue());
params.set(params.get() * primes[2]);
- break;
- default:
+ }
+ default ->
+ {
assertEquals(longLongName, field.getName());
assertEquals(longLongValue, field.getValue());
params.set(params.get() * primes[3]);
- break;
+ }
}
}
@@ -112,7 +117,7 @@ public class ClientGeneratorTest
}
});
- for (ByteBuffer buffer : result.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
@@ -122,17 +127,18 @@ public class ClientGeneratorTest
// Parse again byte by byte
params.set(1);
- for (ByteBuffer buffer : result.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
buffer.flip();
while (buffer.hasRemaining())
{
parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
}
- assertFalse(buffer.hasRemaining());
}
assertEquals(value, params.get());
+
+ accumulator.release();
}
@Test
@@ -147,16 +153,17 @@ public class ClientGeneratorTest
testGenerateRequestContent(128 * 1024);
}
- private void testGenerateRequestContent(final int contentLength) throws Exception
+ private void testGenerateRequestContent(int contentLength) throws Exception
{
ByteBuffer content = ByteBuffer.allocate(contentLength);
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ClientGenerator generator = new ClientGenerator(byteBufferPool);
- final int id = 13;
- Generator.Result result = generator.generateRequestContent(id, content, true, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ClientGenerator generator = new ClientGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ int id = 13;
+ generator.generateRequestContent(accumulator, id, content, true);
- final AtomicInteger totalLength = new AtomicInteger();
+ AtomicInteger totalLength = new AtomicInteger();
ServerParser parser = new ServerParser(new ServerParser.Listener.Adapter()
{
@Override
@@ -175,21 +182,22 @@ public class ClientGeneratorTest
}
});
- for (ByteBuffer buffer : result.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
}
// Parse again one byte at a time
- for (ByteBuffer buffer : result.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
buffer.flip();
while (buffer.hasRemaining())
{
parser.parse(ByteBuffer.wrap(new byte[]{buffer.get()}));
}
- assertFalse(buffer.hasRemaining());
}
+
+ accumulator.release();
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java
index cd673377953..64f2b48e52a 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-client/src/test/java/org/eclipse/jetty/fcgi/parser/ClientParserTest.java
@@ -19,12 +19,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.jetty.fcgi.FCGI;
-import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.fcgi.generator.ServerGenerator;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -34,32 +33,33 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class ClientParserTest
{
@Test
- public void testParseResponseHeaders() throws Exception
+ public void testParseResponseHeaders()
{
- final int id = 13;
+ int id = 13;
HttpFields.Mutable fields = HttpFields.build();
- final int statusCode = 200;
- final String statusMessage = "OK";
- final String contentTypeName = "Content-Type";
- final String contentTypeValue = "text/html;charset=utf-8";
+ int statusCode = 200;
+ String statusMessage = "OK";
+ String contentTypeName = "Content-Type";
+ String contentTypeValue = "text/html;charset=utf-8";
fields.put(contentTypeName, contentTypeValue);
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ServerGenerator generator = new ServerGenerator(byteBufferPool);
- Generator.Result result = generator.generateResponseHeaders(id, statusCode, statusMessage, fields, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ServerGenerator generator = new ServerGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateResponseHeaders(accumulator, id, statusCode, statusMessage, fields);
// Use the fundamental theorem of arithmetic to test the results.
// This way we know onHeader() has been called the right number of
// times with the right arguments, and so onHeaders().
- final int[] primes = new int[]{2, 3, 5};
+ int[] primes = new int[]{2, 3, 5};
int value = 1;
for (int prime : primes)
{
value *= prime;
}
- final AtomicInteger params = new AtomicInteger(1);
+ AtomicInteger params = new AtomicInteger(1);
ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter()
{
@Override
@@ -74,14 +74,10 @@ public class ClientParserTest
public void onHeader(int request, HttpField field)
{
assertEquals(id, request);
- switch (field.getName())
+ if (field.getName().equals(contentTypeName))
{
- case contentTypeName:
- assertEquals(contentTypeValue, field.getValue().toLowerCase(Locale.ENGLISH));
- params.set(params.get() * primes[1]);
- break;
- default:
- break;
+ assertEquals(contentTypeValue, field.getValue().toLowerCase(Locale.ENGLISH));
+ params.set(params.get() * primes[1]);
}
}
@@ -94,28 +90,31 @@ public class ClientParserTest
}
});
- for (ByteBuffer buffer : result.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
}
assertEquals(value, params.get());
+
+ accumulator.release();
}
@Test
public void testParseNoResponseContent() throws Exception
{
- final int id = 13;
+ int id = 13;
HttpFields fields = HttpFields.build()
.put("Content-Length", "0");
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ServerGenerator generator = new ServerGenerator(byteBufferPool);
- Generator.Result result1 = generator.generateResponseHeaders(id, 200, "OK", fields, null);
- Generator.Result result2 = generator.generateResponseContent(id, null, true, false, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ServerGenerator generator = new ServerGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateResponseHeaders(accumulator, id, 200, "OK", fields);
+ generator.generateResponseContent(accumulator, id, null, true, false);
- final AtomicInteger verifier = new AtomicInteger();
+ AtomicInteger verifier = new AtomicInteger();
ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter()
{
@Override
@@ -134,40 +133,38 @@ public class ClientParserTest
}
});
- for (ByteBuffer buffer : result1.getByteBuffers())
- {
- parser.parse(buffer);
- assertFalse(buffer.hasRemaining());
- }
- for (ByteBuffer buffer : result2.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
}
assertEquals(3, verifier.get());
+
+ accumulator.release();
}
@Test
public void testParseSmallResponseContent() throws Exception
{
- final int id = 13;
+ int id = 13;
HttpFields.Mutable fields = HttpFields.build();
ByteBuffer content = ByteBuffer.wrap(new byte[1024]);
- final int contentLength = content.remaining();
+ int contentLength = content.remaining();
- final int code = 200;
- final String contentTypeName = "Content-Length";
- final String contentTypeValue = String.valueOf(contentLength);
+ int code = 200;
+ String contentTypeName = "Content-Length";
+ String contentTypeValue = String.valueOf(contentLength);
fields.put(contentTypeName, contentTypeValue);
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ServerGenerator generator = new ServerGenerator(byteBufferPool);
- Generator.Result result1 = generator.generateResponseHeaders(id, code, "OK", fields, null);
- Generator.Result result2 = generator.generateResponseContent(id, content, true, false, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ServerGenerator generator = new ServerGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateResponseHeaders(accumulator, id, code, "OK", fields);
+ generator.generateResponseContent(accumulator, id, content, true, false);
- final AtomicInteger verifier = new AtomicInteger();
+ AtomicInteger verifier = new AtomicInteger();
ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter()
{
@Override
@@ -187,41 +184,39 @@ public class ClientParserTest
}
});
- for (ByteBuffer buffer : result1.getByteBuffers())
- {
- parser.parse(buffer);
- assertFalse(buffer.hasRemaining());
- }
- for (ByteBuffer buffer : result2.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
}
assertEquals(5, verifier.get());
+
+ accumulator.release();
}
@Test
public void testParseLargeResponseContent() throws Exception
{
- final int id = 13;
+ int id = 13;
HttpFields.Mutable fields = HttpFields.build();
ByteBuffer content = ByteBuffer.wrap(new byte[128 * 1024]);
- final int contentLength = content.remaining();
+ int contentLength = content.remaining();
- final int code = 200;
- final String contentTypeName = "Content-Length";
- final String contentTypeValue = String.valueOf(contentLength);
+ int code = 200;
+ String contentTypeName = "Content-Length";
+ String contentTypeValue = String.valueOf(contentLength);
fields.put(contentTypeName, contentTypeValue);
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ServerGenerator generator = new ServerGenerator(byteBufferPool);
- Generator.Result result1 = generator.generateResponseHeaders(id, code, "OK", fields, null);
- Generator.Result result2 = generator.generateResponseContent(id, content, true, false, null);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ ServerGenerator generator = new ServerGenerator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateResponseHeaders(accumulator, id, code, "OK", fields);
+ generator.generateResponseContent(accumulator, id, content, true, false);
- final AtomicInteger totalLength = new AtomicInteger();
- final AtomicBoolean verifier = new AtomicBoolean();
+ AtomicInteger totalLength = new AtomicInteger();
+ AtomicBoolean verifier = new AtomicBoolean();
ClientParser parser = new ClientParser(new ClientParser.Listener.Adapter()
{
@Override
@@ -241,17 +236,14 @@ public class ClientParserTest
}
});
- for (ByteBuffer buffer : result1.getByteBuffers())
- {
- parser.parse(buffer);
- assertFalse(buffer.hasRemaining());
- }
- for (ByteBuffer buffer : result2.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
}
assertTrue(verifier.get());
+
+ accumulator.release();
}
}
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
index 885d6924c87..964ade042da 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/HttpStreamOverFCGI.java
@@ -18,7 +18,6 @@ import java.util.Locale;
import org.eclipse.jetty.fcgi.FCGI;
import org.eclipse.jetty.fcgi.generator.Flusher;
-import org.eclipse.jetty.fcgi.generator.Generator;
import org.eclipse.jetty.fcgi.generator.ServerGenerator;
import org.eclipse.jetty.http.HostPortHttpField;
import org.eclipse.jetty.http.HttpField;
@@ -30,6 +29,7 @@ import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpStream;
import org.eclipse.jetty.util.BufferUtil;
@@ -229,8 +229,9 @@ public class HttpStreamOverFCGI implements HttpStream
{
if (last)
{
- Generator.Result result = generateResponseContent(true, BufferUtil.EMPTY_BUFFER, callback);
- flusher.flush(result);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generateResponseContent(accumulator, true, BufferUtil.EMPTY_BUFFER);
+ flusher.flush(accumulator, callback);
}
else
{
@@ -240,8 +241,9 @@ public class HttpStreamOverFCGI implements HttpStream
}
else
{
- Generator.Result result = generateResponseContent(last, content, callback);
- flusher.flush(result);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generateResponseContent(accumulator, last, content);
+ flusher.flush(accumulator, callback);
}
if (last && _shutdown)
@@ -258,40 +260,42 @@ public class HttpStreamOverFCGI implements HttpStream
boolean shutdown = _shutdown = info.getFields().contains(HttpHeader.CONNECTION, HttpHeaderValue.CLOSE.asString());
+ RetainableByteBufferPool bufferPool = _generator.getRetainableByteBufferPool();
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
Flusher flusher = _connection.getFlusher();
if (head)
{
if (last)
{
- Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
- Generator.Result contentResult = generateResponseContent(true, BufferUtil.EMPTY_BUFFER, callback);
- flusher.flush(headersResult, contentResult);
+ generateResponseHeaders(accumulator, info);
+ generateResponseContent(accumulator, true, BufferUtil.EMPTY_BUFFER);
+ flusher.flush(accumulator, callback);
}
else
{
- Generator.Result headersResult = generateResponseHeaders(info, callback);
- flusher.flush(headersResult);
+ generateResponseHeaders(accumulator, info);
+ flusher.flush(accumulator, callback);
}
}
else
{
- Generator.Result headersResult = generateResponseHeaders(info, Callback.NOOP);
- Generator.Result contentResult = generateResponseContent(last, content, callback);
- flusher.flush(headersResult, contentResult);
+ generateResponseHeaders(accumulator, info);
+ generateResponseContent(accumulator, last, content);
+ flusher.flush(accumulator, callback);
}
if (last && shutdown)
flusher.shutdown();
}
- private Generator.Result generateResponseHeaders(MetaData.Response info, Callback callback)
+ private void generateResponseHeaders(RetainableByteBufferPool.Accumulator accumulator, MetaData.Response info)
{
- return _generator.generateResponseHeaders(_id, info.getStatus(), info.getReason(), info.getFields(), callback);
+ _generator.generateResponseHeaders(accumulator, _id, info.getStatus(), info.getReason(), info.getFields());
}
- private Generator.Result generateResponseContent(boolean last, ByteBuffer buffer, Callback callback)
+ private void generateResponseContent(RetainableByteBufferPool.Accumulator accumulator, boolean last, ByteBuffer buffer)
{
- return _generator.generateResponseContent(_id, buffer, last, _aborted, callback);
+ _generator.generateResponseContent(accumulator, _id, buffer, last, _aborted);
}
@Override
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
index c6bc575bfc0..c1c6fc75eba 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/main/java/org/eclipse/jetty/fcgi/server/internal/ServerFCGIConnection.java
@@ -63,7 +63,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti
{
super(endPoint, connector.getExecutor());
this.connector = connector;
- this.networkByteBufferPool = connector.getByteBufferPool().asRetainableByteBufferPool();
+ this.networkByteBufferPool = connector.getRetainableByteBufferPool();
this.flusher = new Flusher(endPoint);
this.configuration = configuration;
this.sendStatus200 = sendStatus200;
@@ -212,7 +212,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti
LOG.debug("Read {} bytes from {} {}", read, getEndPoint(), this);
if (read > 0)
{
- if (parse(networkBuffer.getBuffer()))
+ if (parse(networkBuffer.getByteBuffer()))
return;
}
else if (read == 0)
@@ -252,7 +252,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti
// See also HttpConnection.parseAndFillForContent().
while (stream != null)
{
- if (parse(networkBuffer.getBuffer()))
+ if (parse(networkBuffer.getByteBuffer()))
return;
// Check if the request was completed by the parsing.
if (stream == null)
@@ -281,7 +281,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti
{
try
{
- return getEndPoint().fill(networkBuffer.getBuffer());
+ return getEndPoint().fill(networkBuffer.getByteBuffer());
}
catch (Throwable x)
{
@@ -333,7 +333,7 @@ public class ServerFCGIConnection extends AbstractConnection implements Connecti
if (stream != null)
throw new UnsupportedOperationException("FastCGI Multiplexing");
HttpChannel channel = httpChannelFactory.newHttpChannel(ServerFCGIConnection.this);
- ServerGenerator generator = new ServerGenerator(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), sendStatus200);
+ ServerGenerator generator = new ServerGenerator(connector.getRetainableByteBufferPool(), isUseOutputDirectByteBuffers(), sendStatus200);
stream = new HttpStreamOverFCGI(ServerFCGIConnection.this, generator, channel, request);
channel.setHttpStream(stream);
if (LOG.isDebugEnabled())
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
index 6c202372cbb..d35e81805b5 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/AbstractHttpClientServerTest.java
@@ -21,10 +21,9 @@ import org.eclipse.jetty.client.HttpClientTransport;
import org.eclipse.jetty.client.LeakTrackingConnectionPool;
import org.eclipse.jetty.fcgi.client.transport.HttpClientTransportOverFCGI;
import org.eclipse.jetty.http.HttpScheme;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.ClientConnector;
-import org.eclipse.jetty.io.LeakTrackingByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
@@ -39,8 +38,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
public abstract class AbstractHttpClientServerTest
{
- private LeakTrackingByteBufferPool serverBufferPool;
- protected ByteBufferPool clientBufferPool;
+ private RetainableByteBufferPool serverBufferPool;
+ protected RetainableByteBufferPool clientBufferPool;
private final AtomicLong connectionLeaks = new AtomicLong();
protected Server server;
protected ServerConnector connector;
@@ -53,7 +52,8 @@ public abstract class AbstractHttpClientServerTest
serverThreads.setName("server");
server = new Server(serverThreads);
ServerFCGIConnectionFactory fcgiConnectionFactory = new ServerFCGIConnectionFactory(new HttpConfiguration());
- serverBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
+ // TODO: restore leak tracking.
+ serverBufferPool = new ArrayRetainableByteBufferPool();
connector = new ServerConnector(server, null, null, serverBufferPool,
1, Math.max(1, ProcessorUtils.availableProcessors() / 2), fcgiConnectionFactory);
server.addConnector(connector);
@@ -65,9 +65,10 @@ public abstract class AbstractHttpClientServerTest
QueuedThreadPool clientThreads = new QueuedThreadPool();
clientThreads.setName("client");
clientConnector.setExecutor(clientThreads);
+ // TODO: restore leak tracking.
if (clientBufferPool == null)
- clientBufferPool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged());
- clientConnector.setByteBufferPool(clientBufferPool);
+ clientBufferPool = new ArrayRetainableByteBufferPool();
+ clientConnector.setRetainableByteBufferPool(clientBufferPool);
HttpClientTransport transport = new HttpClientTransportOverFCGI(clientConnector, "");
transport.setConnectionPoolFactory(destination -> new LeakTrackingConnectionPool(destination, client.getMaxConnectionsPerDestination())
{
@@ -86,22 +87,6 @@ public abstract class AbstractHttpClientServerTest
{
System.gc();
- if (serverBufferPool != null)
- {
- assertThat("Server BufferPool - leaked acquires", serverBufferPool.getLeakedAcquires(), Matchers.is(0L));
- assertThat("Server BufferPool - leaked releases", serverBufferPool.getLeakedReleases(), Matchers.is(0L));
- assertThat("Server BufferPool - leaked removes", serverBufferPool.getLeakedRemoves(), Matchers.is(0L));
- assertThat("Server BufferPool - unreleased", serverBufferPool.getLeakedResources(), Matchers.is(0L));
- }
-
- if ((clientBufferPool != null) && (clientBufferPool instanceof LeakTrackingByteBufferPool pool))
- {
- assertThat("Client BufferPool - leaked acquires", pool.getLeakedAcquires(), Matchers.is(0L));
- assertThat("Client BufferPool - leaked releases", pool.getLeakedReleases(), Matchers.is(0L));
- assertThat("Client BufferPool - leaked removes", pool.getLeakedRemoves(), Matchers.is(0L));
- assertThat("Client BufferPool - unreleased", pool.getLeakedResources(), Matchers.is(0L));
- }
-
assertThat("Connection Leaks", connectionLeaks.get(), Matchers.is(0L));
if (client != null)
diff --git a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
index b33600070d3..11924579772 100644
--- a/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
+++ b/jetty-core/jetty-fcgi/jetty-fcgi-server/src/test/java/org/eclipse/jetty/fcgi/server/HttpClientTest.java
@@ -36,7 +36,6 @@ import org.eclipse.jetty.client.Response;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.io.Content;
-import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
@@ -400,11 +399,6 @@ public class HttpClientTest extends AbstractHttpClientServerTest
@Test
public void testGZIPContentEncoding() throws Exception
{
- // GZIPContentDecoder returns to application pooled
- // buffers, which is fine, but in this test they will
- // appear as "leaked", so we use a normal ByteBufferPool.
- clientBufferPool = new MappedByteBufferPool.Tagged();
-
byte[] data = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
start(new Handler.Abstract()
{
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
index 7a84fc3ca5d..b176ba3bb82 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/GZIPContentDecoder.java
@@ -13,7 +13,6 @@
package org.eclipse.jetty.http;
-import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -21,7 +20,8 @@ import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import java.util.zip.ZipException;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.component.Destroyable;
import org.eclipse.jetty.util.compression.InflaterPool;
@@ -36,8 +36,8 @@ public class GZIPContentDecoder implements Destroyable
// Unsigned Integer Max == 2^32
private static final long UINT_MAX = 0xFFFFFFFFL;
- private final List _inflateds = new ArrayList<>();
- private final ByteBufferPool _pool;
+ private final List _inflateds = new ArrayList<>();
+ private final RetainableByteBufferPool _pool;
private final int _bufferSize;
private InflaterPool.Entry _inflaterEntry;
private Inflater _inflater;
@@ -45,7 +45,7 @@ public class GZIPContentDecoder implements Destroyable
private int _size;
private long _value;
private byte _flags;
- private ByteBuffer _inflated;
+ private RetainableByteBuffer _inflated;
public GZIPContentDecoder()
{
@@ -57,24 +57,24 @@ public class GZIPContentDecoder implements Destroyable
this(null, bufferSize);
}
- public GZIPContentDecoder(ByteBufferPool pool, int bufferSize)
+ public GZIPContentDecoder(RetainableByteBufferPool retainableByteBufferPool, int bufferSize)
{
- this(new InflaterPool(0, true), pool, bufferSize);
+ this(new InflaterPool(0, true), retainableByteBufferPool, bufferSize);
}
- public GZIPContentDecoder(InflaterPool inflaterPool, ByteBufferPool pool, int bufferSize)
+ public GZIPContentDecoder(InflaterPool inflaterPool, RetainableByteBufferPool retainableByteBufferPool, int bufferSize)
{
_inflaterEntry = inflaterPool.acquire();
_inflater = _inflaterEntry.get();
_bufferSize = bufferSize;
- _pool = pool;
+ _pool = retainableByteBufferPool != null ? retainableByteBufferPool : new RetainableByteBufferPool.NonPooling();
reset();
}
/**
*
Inflates compressed data from a buffer.
- *
The buffers returned by this method should be released
- * via {@link #release(ByteBuffer)}.
+ *
The {@link RetainableByteBuffer} returned by this method
+ * must be released via {@link RetainableByteBuffer#release()}.
*
This method may fully consume the input buffer, but return
* only a chunk of the inflated bytes, to allow applications to
* consume the inflated chunk before performing further inflation,
@@ -83,21 +83,21 @@ public class GZIPContentDecoder implements Destroyable
* it's already fully consumed) and that will produce another
* chunk of inflated bytes. Termination happens when the input
* buffer is fully consumed, and the returned buffer is empty.
- *
See {@link #decodedChunk(ByteBuffer)} to perform inflating
+ *
See {@link #decodedChunk(RetainableByteBuffer)} to perform inflating
* in a non-blocking way that allows to apply backpressure.
*
* @param compressed the buffer containing compressed data.
* @return a buffer containing inflated data.
*/
- public ByteBuffer decode(ByteBuffer compressed)
+ public RetainableByteBuffer decode(ByteBuffer compressed)
{
decodeChunks(compressed);
if (_inflateds.isEmpty())
{
- if (BufferUtil.isEmpty(_inflated) || _state == State.CRC || _state == State.ISIZE)
- return BufferUtil.EMPTY_BUFFER;
- ByteBuffer result = _inflated;
+ if ((_inflated == null || !_inflated.hasRemaining()) || _state == State.CRC || _state == State.ISIZE)
+ return acquire(0);
+ RetainableByteBuffer result = _inflated;
_inflated = null;
return result;
}
@@ -105,12 +105,12 @@ public class GZIPContentDecoder implements Destroyable
{
_inflateds.add(_inflated);
_inflated = null;
- int length = _inflateds.stream().mapToInt(Buffer::remaining).sum();
- ByteBuffer result = acquire(length);
- for (ByteBuffer buffer : _inflateds)
+ int length = _inflateds.stream().mapToInt(RetainableByteBuffer::remaining).sum();
+ RetainableByteBuffer result = acquire(length);
+ for (RetainableByteBuffer buffer : _inflateds)
{
- BufferUtil.append(result, buffer);
- release(buffer);
+ BufferUtil.append(result.getByteBuffer(), buffer.getByteBuffer());
+ buffer.release();
}
_inflateds.clear();
return result;
@@ -132,38 +132,26 @@ public class GZIPContentDecoder implements Destroyable
* should return, allowing to consume the inflated chunk and apply
* backpressure
*/
- protected boolean decodedChunk(ByteBuffer chunk)
+ protected boolean decodedChunk(RetainableByteBuffer chunk)
{
- if (_inflated == null)
- {
- _inflated = chunk;
- }
- else
- {
- if (BufferUtil.space(_inflated) >= chunk.remaining())
- {
- BufferUtil.append(_inflated, chunk);
- release(chunk);
- }
- else
- {
- _inflateds.add(_inflated);
- _inflated = chunk;
- }
- }
+ // Retain the chunk because it is stored for later use.
+ chunk.retain();
+ if (_inflated != null)
+ _inflateds.add(_inflated);
+ _inflated = chunk;
return false;
}
/**
*
Inflates compressed data.
*
Inflation continues until the compressed block end is reached, there is no
- * more compressed data or a call to {@link #decodedChunk(ByteBuffer)} returns true.
+ * more compressed data or a call to {@link #decodedChunk(RetainableByteBuffer)} returns true.
*
* @param compressed the buffer of compressed data to inflate
*/
protected void decodeChunks(ByteBuffer compressed)
{
- ByteBuffer buffer = null;
+ RetainableByteBuffer buffer = null;
try
{
while (true)
@@ -211,9 +199,10 @@ public class GZIPContentDecoder implements Destroyable
try
{
- int pos = BufferUtil.flipToFill(buffer);
- _inflater.inflate(buffer);
- BufferUtil.flipToFlush(buffer, pos);
+ ByteBuffer decoded = buffer.getByteBuffer();
+ int pos = BufferUtil.flipToFill(decoded);
+ _inflater.inflate(decoded);
+ BufferUtil.flipToFlush(decoded, pos);
}
catch (DataFormatException x)
{
@@ -222,9 +211,10 @@ public class GZIPContentDecoder implements Destroyable
if (buffer.hasRemaining())
{
- ByteBuffer decoded = buffer;
+ boolean stop = decodedChunk(buffer);
+ buffer.release();
buffer = null;
- if (decodedChunk(decoded))
+ if (stop)
return;
}
else if (_inflater.needsInput())
@@ -395,7 +385,7 @@ public class GZIPContentDecoder implements Destroyable
finally
{
if (buffer != null)
- release(buffer);
+ buffer.release();
}
}
@@ -430,23 +420,8 @@ public class GZIPContentDecoder implements Destroyable
* @param capacity capacity of the ByteBuffer to acquire
* @return a heap buffer of the configured capacity either from the pool or freshly allocated.
*/
- public ByteBuffer acquire(int capacity)
+ public RetainableByteBuffer acquire(int capacity)
{
- return _pool == null ? BufferUtil.allocate(capacity) : _pool.acquire(capacity, false);
- }
-
- /**
- *
Releases an allocated buffer.
- *
This method calls {@link ByteBufferPool#release(ByteBuffer)} if a buffer pool has
- * been configured.
- *
This method should be called once for all buffers returned from {@link #decode(ByteBuffer)}
- * or passed to {@link #decodedChunk(ByteBuffer)}.
- *
- * @param buffer the buffer to release.
- */
- public void release(ByteBuffer buffer)
- {
- if (_pool != null && !BufferUtil.isTheEmptyBuffer(buffer))
- _pool.release(buffer);
+ return _pool.acquire(capacity, false);
}
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/CachingHttpContentFactory.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/CachingHttpContentFactory.java
index cce551591d8..120e26ee903 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/CachingHttpContentFactory.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/CachingHttpContentFactory.java
@@ -30,9 +30,9 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.http.PreEncodedHttpField;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.NoopByteBufferPool;
import org.eclipse.jetty.io.Retainable;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.NanoTime;
import org.eclipse.jetty.util.StringUtil;
@@ -69,16 +69,16 @@ public class CachingHttpContentFactory implements HttpContent.Factory
private final HttpContent.Factory _authority;
private final ConcurrentHashMap _cache = new ConcurrentHashMap<>();
private final AtomicLong _cachedSize = new AtomicLong();
- private final ByteBufferPool _byteBufferPool;
+ private final RetainableByteBufferPool _bufferPool;
private int _maxCachedFileSize = DEFAULT_MAX_CACHED_FILE_SIZE;
private int _maxCachedFiles = DEFAULT_MAX_CACHED_FILES;
private long _maxCacheSize = DEFAULT_MAX_CACHE_SIZE;
private boolean _useDirectByteBuffers = true;
- public CachingHttpContentFactory(HttpContent.Factory authority, ByteBufferPool byteBufferPool)
+ public CachingHttpContentFactory(HttpContent.Factory authority, RetainableByteBufferPool bufferPool)
{
_authority = authority;
- _byteBufferPool = (byteBufferPool == null) ? new NoopByteBufferPool() : byteBufferPool;
+ _bufferPool = bufferPool != null ? bufferPool : new RetainableByteBufferPool.NonPooling();
}
protected ConcurrentMap getCache()
@@ -294,7 +294,7 @@ public class CachingHttpContentFactory implements HttpContent.Factory
protected class CachedHttpContent extends HttpContent.Wrapper implements CachingHttpContent
{
- private final ByteBuffer _buffer;
+ private final RetainableByteBuffer _buffer;
private final String _cacheKey;
private final HttpField _etagField;
private final long _contentLengthValue;
@@ -327,21 +327,23 @@ public class CachingHttpContentFactory implements HttpContent.Factory
boolean isValid = true;
// Read the content into memory if the HttpContent does not already have a buffer.
+ RetainableByteBuffer buffer;
ByteBuffer byteBuffer = httpContent.getByteBuffer();
if (byteBuffer == null)
{
+ buffer = _bufferPool.acquire((int)_contentLengthValue, _useDirectByteBuffers);
try
{
if (_contentLengthValue <= _maxCachedFileSize)
{
- byteBuffer = _byteBufferPool.acquire((int)_contentLengthValue, _useDirectByteBuffers);
try (ReadableByteChannel readableByteChannel = httpContent.getResource().newReadableByteChannel())
{
+ byteBuffer = buffer.getByteBuffer();
int read = BufferUtil.readFrom(readableByteChannel, byteBuffer);
if (read != _contentLengthValue)
{
- _byteBufferPool.release(byteBuffer);
- byteBuffer = null;
+ buffer.release();
+ buffer = null;
isValid = false;
}
}
@@ -349,17 +351,19 @@ public class CachingHttpContentFactory implements HttpContent.Factory
}
catch (Throwable t)
{
+ if (buffer != null)
+ buffer.release();
+ buffer = null;
isValid = false;
- if (byteBuffer != null)
- {
- _byteBufferPool.release(byteBuffer);
- byteBuffer = null;
- }
LOG.warn("Failed to read Resource", t);
}
}
+ else
+ {
+ buffer = RetainableByteBuffer.wrap(byteBuffer);
+ }
- _buffer = byteBuffer;
+ _buffer = buffer;
_isValid = isValid;
_bytesOccupied = httpContent.getBytesOccupied();
_lastModifiedValue = httpContent.getLastModifiedValue();
@@ -381,7 +385,7 @@ public class CachingHttpContentFactory implements HttpContent.Factory
@Override
public ByteBuffer getByteBuffer()
{
- return _buffer == null ? null : _buffer.asReadOnlyBuffer();
+ return _buffer == null ? null : _buffer.getByteBuffer().asReadOnlyBuffer();
}
@Override
@@ -420,7 +424,7 @@ public class CachingHttpContentFactory implements HttpContent.Factory
if (_referenceCount.release())
{
if (_buffer != null)
- _byteBufferPool.release(_buffer);
+ _buffer.release();
super.release();
}
}
diff --git a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java
index 4581b0d4144..b3dea606cf7 100644
--- a/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java
+++ b/jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/content/ValidatingCachingHttpContentFactory.java
@@ -19,7 +19,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.NanoTime;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.thread.Scheduler;
@@ -55,13 +55,13 @@ public class ValidatingCachingHttpContentFactory extends CachingHttpContentFacto
*
* @param authority the wrapped {@link HttpContent.Factory} to use.
* @param validationPeriod time between filesystem checks in ms to see if an {@link HttpContent} is still valid (-1 never validate, 0 always validate).
- * @param byteBufferPool the {@link org.eclipse.jetty.io.ByteBufferPool} to use.
+ * @param bufferPool the {@link org.eclipse.jetty.io.RetainableByteBufferPool} to use.
*/
public ValidatingCachingHttpContentFactory(@Name("authority") HttpContent.Factory authority,
@Name("validationPeriod") long validationPeriod,
- @Name("byteBufferPool") ByteBufferPool byteBufferPool)
+ @Name("bufferPool") RetainableByteBufferPool bufferPool)
{
- this(authority, validationPeriod, byteBufferPool, null, -1, -1);
+ this(authority, validationPeriod, bufferPool, null, -1, -1);
}
/**
@@ -70,19 +70,19 @@ public class ValidatingCachingHttpContentFactory extends CachingHttpContentFacto
*
* @param authority the wrapped {@link HttpContent.Factory} to use.
* @param validationPeriod time between filesystem checks in ms to see if an {@link HttpContent} is still valid (-1 never validate, 0 always validate).
- * @param byteBufferPool the {@link org.eclipse.jetty.io.ByteBufferPool} to use.
+ * @param bufferPool the {@link org.eclipse.jetty.io.RetainableByteBufferPool} to use.
* @param scheduler scheduler to use for the sweeper, can be null to not use sweeper.
* @param sweepPeriod time between runs of the sweeper in ms (if 0 never sweep for invalid entries).
* @param idleTimeout amount of time in ms an entry can be unused before evicted by the sweeper (if 0 never evict unused entries).
*/
public ValidatingCachingHttpContentFactory(@Name("authority") HttpContent.Factory authority,
@Name("validationPeriod") long validationPeriod,
- @Name("byteBufferPool") ByteBufferPool byteBufferPool,
+ @Name("byteBufferPool") RetainableByteBufferPool bufferPool,
@Name("scheduler") Scheduler scheduler,
@Name("sweepPeriod") long sweepPeriod,
@Name("idleTimeout") long idleTimeout)
{
- super(authority, byteBufferPool);
+ super(authority, bufferPool);
_validationTime = validationPeriod;
_scheduler = scheduler;
_sweepDelay = sweepPeriod;
diff --git a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java
index b0f2916f43c..75e4161d423 100644
--- a/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java
+++ b/jetty-core/jetty-http/src/test/java/org/eclipse/jetty/http/GZIPContentDecoderTest.java
@@ -23,7 +23,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
-import org.eclipse.jetty.io.ArrayByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -39,28 +41,29 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class GZIPContentDecoderTest
{
- private ArrayByteBufferPool pool;
- private AtomicInteger buffers = new AtomicInteger(0);
+ private final AtomicInteger counter = new AtomicInteger();
+ private RetainableByteBufferPool pool;
@BeforeEach
public void before()
{
- buffers.set(0);
- pool = new ArrayByteBufferPool()
+ pool = new RetainableByteBufferPool.Wrapper(new ArrayRetainableByteBufferPool())
{
-
@Override
- public ByteBuffer acquire(int size, boolean direct)
+ public RetainableByteBuffer acquire(int size, boolean direct)
{
- buffers.incrementAndGet();
- return super.acquire(size, direct);
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- buffers.decrementAndGet();
- super.release(buffer);
+ counter.incrementAndGet();
+ return new RetainableByteBuffer.Wrapper(super.acquire(size, direct))
+ {
+ @Override
+ public boolean release()
+ {
+ boolean released = super.release();
+ if (released)
+ counter.decrementAndGet();
+ return released;
+ }
+ };
}
};
}
@@ -68,7 +71,7 @@ public class GZIPContentDecoderTest
@AfterEach
public void after()
{
- assertEquals(0, buffers.get());
+ assertThat(counter.get(), is(0));
}
@Test
@@ -126,8 +129,9 @@ public class GZIPContentDecoderTest
byte[] bytes = baos.toByteArray();
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
assertEquals(0, decoded.remaining());
+ decoded.release();
}
@Test
@@ -142,9 +146,9 @@ public class GZIPContentDecoderTest
byte[] bytes = baos.toByteArray();
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
- assertEquals(data, StandardCharsets.UTF_8.decode(decoded).toString());
- decoder.release(decoded);
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes));
+ assertEquals(data, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
+ decoded.release();
}
@Test
@@ -165,11 +169,12 @@ public class GZIPContentDecoderTest
System.arraycopy(bytes, bytes1.length, bytes2, 0, bytes2.length);
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
- assertEquals(0, decoded.capacity());
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
+ assertEquals(0, decoded.remaining());
+ decoded.release();
decoded = decoder.decode(ByteBuffer.wrap(bytes2));
- assertEquals(data, StandardCharsets.UTF_8.decode(decoded).toString());
- decoder.release(decoded);
+ assertEquals(data, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
+ decoded.release();
}
@Test
@@ -190,14 +195,14 @@ public class GZIPContentDecoderTest
System.arraycopy(bytes, bytes1.length, bytes2, 0, bytes2.length);
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
- assertEquals(data, StandardCharsets.UTF_8.decode(decoded).toString());
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
+ assertEquals(data, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
assertFalse(decoder.isFinished());
- decoder.release(decoded);
+ decoded.release();
decoded = decoder.decode(ByteBuffer.wrap(bytes2));
assertEquals(0, decoded.remaining());
assertTrue(decoder.isFinished());
- decoder.release(decoded);
+ decoded.release();
}
@Test
@@ -218,12 +223,12 @@ public class GZIPContentDecoderTest
System.arraycopy(bytes, bytes1.length, bytes2, 0, bytes2.length);
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
- assertEquals(0, decoded.capacity());
- decoder.release(decoded);
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
+ assertEquals(0, decoded.remaining());
+ decoded.release();
decoded = decoder.decode(ByteBuffer.wrap(bytes2));
- assertEquals(data, StandardCharsets.UTF_8.decode(decoded).toString());
- decoder.release(decoded);
+ assertEquals(data, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
+ decoded.release();
}
@Test
@@ -249,16 +254,16 @@ public class GZIPContentDecoderTest
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
ByteBuffer buffer = ByteBuffer.wrap(bytes);
- ByteBuffer decoded = decoder.decode(buffer);
- assertEquals(data1, StandardCharsets.UTF_8.decode(decoded).toString());
+ RetainableByteBuffer decoded = decoder.decode(buffer);
+ assertEquals(data1, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
assertTrue(decoder.isFinished());
assertTrue(buffer.hasRemaining());
- decoder.release(decoded);
+ decoded.release();
decoded = decoder.decode(buffer);
- assertEquals(data2, StandardCharsets.UTF_8.decode(decoded).toString());
+ assertEquals(data2, StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString());
assertTrue(decoder.isFinished());
assertFalse(buffer.hasRemaining());
- decoder.release(decoded);
+ decoded.release();
}
@Test
@@ -280,9 +285,9 @@ public class GZIPContentDecoderTest
ByteBuffer buffer = ByteBuffer.wrap(bytes);
while (buffer.hasRemaining())
{
- ByteBuffer decoded = decoder.decode(buffer);
- result += StandardCharsets.UTF_8.decode(decoded).toString();
- decoder.release(decoded);
+ RetainableByteBuffer decoded = decoder.decode(buffer);
+ result += StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString();
+ decoded.release();
}
assertEquals(data, result);
}
@@ -306,10 +311,10 @@ public class GZIPContentDecoderTest
ByteBuffer buffer = ByteBuffer.wrap(bytes);
while (buffer.hasRemaining())
{
- ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(new byte[]{buffer.get()}));
+ RetainableByteBuffer decoded = decoder.decode(ByteBuffer.wrap(new byte[]{buffer.get()}));
if (decoded.hasRemaining())
- result += StandardCharsets.UTF_8.decode(decoded).toString();
- decoder.release(decoded);
+ result += StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString();
+ decoded.release();
}
assertEquals(data, result);
assertTrue(decoder.isFinished());
@@ -341,10 +346,10 @@ public class GZIPContentDecoderTest
ByteBuffer buffer = ByteBuffer.wrap(bytes);
while (buffer.hasRemaining())
{
- ByteBuffer decoded = decoder.decode(buffer);
+ RetainableByteBuffer decoded = decoder.decode(buffer);
if (decoded.hasRemaining())
- result += StandardCharsets.UTF_8.decode(decoded).toString();
- decoder.release(decoded);
+ result += StandardCharsets.UTF_8.decode(decoded.getByteBuffer()).toString();
+ decoded.release();
if (decoder.isFinished())
break;
}
@@ -414,12 +419,12 @@ public class GZIPContentDecoderTest
ByteBuffer buf = ByteBuffer.wrap(b, off, len);
while (buf.hasRemaining())
{
- ByteBuffer decoded = decoder.decode(buf);
+ RetainableByteBuffer decoded = decoder.decode(buf);
if (decoded.hasRemaining())
{
decodedByteCount += decoded.remaining();
}
- decoder.release(decoded);
+ decoded.release();
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/HttpClientTransportOverHTTP2.java b/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/HttpClientTransportOverHTTP2.java
index 7bd52127165..23fd9c2cfa9 100644
--- a/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/HttpClientTransportOverHTTP2.java
+++ b/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/HttpClientTransportOverHTTP2.java
@@ -90,7 +90,7 @@ public class HttpClientTransportOverHTTP2 extends AbstractHttpClientTransport
HttpClient httpClient = getHttpClient();
client.setExecutor(httpClient.getExecutor());
client.setScheduler(httpClient.getScheduler());
- client.setByteBufferPool(httpClient.getByteBufferPool());
+ client.setRetainableByteBufferPool(httpClient.getRetainableByteBufferPool());
client.setConnectTimeout(httpClient.getConnectTimeout());
client.setIdleTimeout(httpClient.getIdleTimeout());
client.setInputBufferSize(httpClient.getResponseBufferSize());
diff --git a/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpReceiverOverHTTP2.java b/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpReceiverOverHTTP2.java
index d802c1f1507..f935a79265d 100644
--- a/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpReceiverOverHTTP2.java
+++ b/jetty-core/jetty-http2/jetty-http2-client-transport/src/main/java/org/eclipse/jetty/http2/client/transport/internal/HttpReceiverOverHTTP2.java
@@ -76,7 +76,7 @@ public class HttpReceiverOverHTTP2 extends HttpReceiver implements HTTP2Channel.
DataFrame frame = data.frame();
boolean last = frame.remaining() == 0 && frame.isEndStream();
if (!last)
- return Content.Chunk.asChunk(frame.getData(), last, data);
+ return Content.Chunk.asChunk(frame.getByteBuffer(), last, data);
data.release();
responseSuccess(getHttpExchange(), null);
return Content.Chunk.EOF;
diff --git a/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java b/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java
index 368d3009d60..2d488a23e8c 100644
--- a/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java
+++ b/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2Client.java
@@ -28,9 +28,9 @@ import org.eclipse.jetty.http2.FlowControlStrategy;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.ClientConnector;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.ssl.SslClientConnectionFactory;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
@@ -153,14 +153,14 @@ public class HTTP2Client extends ContainerLifeCycle
connector.setScheduler(scheduler);
}
- public ByteBufferPool getByteBufferPool()
+ public RetainableByteBufferPool getRetainableByteBufferPool()
{
- return connector.getByteBufferPool();
+ return connector.getRetainableByteBufferPool();
}
- public void setByteBufferPool(ByteBufferPool bufferPool)
+ public void setRetainableByteBufferPool(RetainableByteBufferPool bufferPool)
{
- connector.setByteBufferPool(bufferPool);
+ connector.setRetainableByteBufferPool(bufferPool);
}
public FlowControlStrategy.Factory getFlowControlStrategyFactory()
@@ -435,7 +435,7 @@ public class HTTP2Client extends ContainerLifeCycle
{
if (isUseALPN())
factory = new ALPNClientConnectionFactory(getExecutor(), factory, getProtocols());
- factory = new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), factory);
+ factory = new SslClientConnectionFactory(sslContextFactory, getRetainableByteBufferPool(), getExecutor(), factory);
}
return factory;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java b/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java
index 3d665b1575f..6937d0db6e4 100644
--- a/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java
+++ b/jetty-core/jetty-http2/jetty-http2-client/src/main/java/org/eclipse/jetty/http2/client/HTTP2ClientConnectionFactory.java
@@ -28,7 +28,6 @@ import org.eclipse.jetty.http2.internal.HTTP2Connection;
import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ClientConnectionFactory;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
@@ -49,14 +48,14 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
public Connection newConnection(EndPoint endPoint, Map context)
{
HTTP2Client client = (HTTP2Client)context.get(CLIENT_CONTEXT_KEY);
- ByteBufferPool byteBufferPool = client.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = client.getRetainableByteBufferPool();
Executor executor = client.getExecutor();
Scheduler scheduler = client.getScheduler();
Session.Listener listener = (Session.Listener)context.get(SESSION_LISTENER_CONTEXT_KEY);
@SuppressWarnings("unchecked")
Promise promise = (Promise)context.get(SESSION_PROMISE_CONTEXT_KEY);
- Generator generator = new Generator(byteBufferPool, client.getMaxDynamicTableSize(), client.getMaxHeaderBlockFragment());
+ Generator generator = new Generator(bufferPool, client.getMaxDynamicTableSize(), client.getMaxHeaderBlockFragment());
FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy();
HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl);
session.setMaxRemoteStreams(client.getMaxConcurrentPushedStreams());
@@ -64,13 +63,11 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
if (streamIdleTimeout > 0)
session.setStreamIdleTimeout(streamIdleTimeout);
- Parser parser = new Parser(byteBufferPool, session, 4096, 8192);
+ Parser parser = new Parser(bufferPool, session, 4096, 8192);
parser.setMaxFrameLength(client.getMaxFrameLength());
parser.setMaxSettingsKeys(client.getMaxSettingsKeys());
- RetainableByteBufferPool retainableByteBufferPool = byteBufferPool.asRetainableByteBufferPool();
-
- HTTP2ClientConnection connection = new HTTP2ClientConnection(client, retainableByteBufferPool, executor, endPoint,
+ HTTP2ClientConnection connection = new HTTP2ClientConnection(client, bufferPool, executor, endPoint,
parser, session, client.getInputBufferSize(), promise, listener);
connection.setUseInputDirectByteBuffers(client.isUseInputDirectByteBuffers());
connection.setUseOutputDirectByteBuffers(client.isUseOutputDirectByteBuffers());
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
index d8003f51fb0..a4cf8c828e1 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/api/Stream.java
@@ -313,10 +313,10 @@ public interface Stream
*
It is always guaranteed that invoking {@link Stream#demand()}
* from within this method will not cause a {@link StackOverflowError}.
*
Typical usage:
- *
+ *
{@code
* class MyStreamListener implements Stream.Listener
* {
- * @Override
+ * @Override
* public void onDataAvailable(Stream stream)
* {
* // Read a chunk of the content.
@@ -329,7 +329,7 @@ public interface Stream
* else
* {
* // Process the content.
- * process(data.getByteBuffer());
+ * process(data.frame().getByteBuffer());
* // Notify that the content has been consumed.
* data.release();
* if (!data.frame().isEndStream())
@@ -340,7 +340,7 @@ public interface Stream
* }
* }
* }
- *
+ * }
*
* @param stream the stream
* @see Stream#demand()
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java
index 9939a502189..3c34edf3ba3 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/frames/DataFrame.java
@@ -39,7 +39,7 @@ public class DataFrame extends StreamFrame
this.padding = padding;
}
- public ByteBuffer getData()
+ public ByteBuffer getByteBuffer()
{
return data;
}
@@ -68,12 +68,12 @@ public class DataFrame extends StreamFrame
@Override
public DataFrame withStreamId(int streamId)
{
- return new DataFrame(streamId, getData(), isEndStream());
+ return new DataFrame(streamId, getByteBuffer(), isEndStream());
}
@Override
public String toString()
{
- return String.format("%s#%d{length:%d,end=%b}", super.toString(), getStreamId(), data.remaining(), endStream);
+ return String.format("%s#%d{length:%d,end=%b}", super.toString(), getStreamId(), remaining(), isEndStream());
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Connection.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Connection.java
index bf7ee9e5b0e..7199617f238 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Connection.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Connection.java
@@ -455,7 +455,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
public ByteBuffer getBuffer()
{
- return delegate.getBuffer();
+ return delegate.getByteBuffer();
}
public boolean isRetained()
@@ -494,7 +494,7 @@ public class HTTP2Connection extends AbstractConnection implements WriteFlusher.
private void put(ByteBuffer source)
{
- BufferUtil.append(delegate.getBuffer(), source);
+ BufferUtil.append(delegate.getByteBuffer(), source);
}
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java
index dc960759ca4..7316190c78a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Flusher.java
@@ -30,8 +30,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.hpack.HpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EofException;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.component.Dumpable;
@@ -51,7 +51,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
private final Queue pendingEntries = new ArrayDeque<>();
private final Collection processedEntries = new ArrayList<>();
private final HTTP2Session session;
- private final ByteBufferPool.Lease lease;
+ private final RetainableByteBufferPool.Accumulator accumulator;
private InvocationType invocationType = InvocationType.NON_BLOCKING;
private Throwable terminated;
private Entry stalledEntry;
@@ -59,7 +59,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
public HTTP2Flusher(HTTP2Session session)
{
this.session = session;
- this.lease = new ByteBufferPool.Lease(session.getGenerator().getByteBufferPool());
+ this.accumulator = new RetainableByteBufferPool.Accumulator();
}
@Override
@@ -213,7 +213,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
try
{
- if (entry.generate(lease))
+ if (entry.generate(accumulator))
{
if (LOG.isDebugEnabled())
LOG.debug("Generated {} frame bytes for {}", entry.getFrameBytesGenerated(), entry);
@@ -266,7 +266,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
break;
int writeThreshold = session.getWriteThreshold();
- if (lease.getTotalLength() >= writeThreshold)
+ if (accumulator.getTotalLength() >= writeThreshold)
{
if (LOG.isDebugEnabled())
LOG.debug("Write threshold {} exceeded", writeThreshold);
@@ -274,7 +274,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
}
}
- List byteBuffers = lease.getByteBuffers();
+ List byteBuffers = accumulator.getByteBuffers();
if (byteBuffers.isEmpty())
{
finish();
@@ -284,7 +284,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
if (LOG.isDebugEnabled())
LOG.debug("Writing {} buffers ({} bytes) - entries processed/pending {}/{}: {}/{}",
byteBuffers.size(),
- lease.getTotalLength(),
+ accumulator.getTotalLength(),
processedEntries.size(),
pendingEntries.size(),
processedEntries,
@@ -308,7 +308,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
{
if (LOG.isDebugEnabled())
LOG.debug("Written {} buffers - entries processed/pending {}/{}: {}/{}",
- lease.getByteBuffers().size(),
+ accumulator.getByteBuffers().size(),
processedEntries.size(),
pendingEntries.size(),
processedEntries,
@@ -319,7 +319,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
private void finish()
{
- lease.recycle();
+ accumulator.release();
processedEntries.forEach(Entry::succeeded);
processedEntries.clear();
@@ -349,7 +349,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
@Override
protected void onCompleteFailure(Throwable x)
{
- lease.recycle();
+ accumulator.release();
Throwable closed;
Set allEntries;
@@ -440,7 +440,7 @@ public class HTTP2Flusher extends IteratingCallback implements Dumpable
return 0;
}
- protected abstract boolean generate(ByteBufferPool.Lease lease) throws HpackException;
+ protected abstract boolean generate(RetainableByteBufferPool.Accumulator accumulator) throws HpackException;
public abstract long onFlushed(long bytes) throws IOException;
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Session.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Session.java
index 9f21c12c23f..27c5079cdd8 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Session.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2Session.java
@@ -57,9 +57,9 @@ import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.hpack.HpackException;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.CyclicTimeouts;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.util.AtomicBiInteger;
import org.eclipse.jetty.util.Atomics;
@@ -1206,9 +1206,9 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
}
@Override
- protected boolean generate(ByteBufferPool.Lease lease) throws HpackException
+ protected boolean generate(RetainableByteBufferPool.Accumulator accumulator) throws HpackException
{
- frameBytes = generator.control(lease, frame);
+ frameBytes = generator.control(accumulator, frame);
beforeSend();
return true;
}
@@ -1320,7 +1320,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
}
@Override
- protected boolean generate(ByteBufferPool.Lease lease)
+ protected boolean generate(RetainableByteBufferPool.Accumulator accumulator)
{
int dataRemaining = getDataBytesRemaining();
@@ -1334,7 +1334,7 @@ public abstract class HTTP2Session extends ContainerLifeCycle implements Session
// Only one DATA frame is generated.
DataFrame dataFrame = (DataFrame)frame;
- int frameBytes = generator.data(lease, dataFrame, length);
+ int frameBytes = generator.data(accumulator, dataFrame, length);
this.frameBytes += frameBytes;
this.frameRemaining += frameBytes;
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2StreamEndPoint.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2StreamEndPoint.java
index c7661179bfe..d402410432a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2StreamEndPoint.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/HTTP2StreamEndPoint.java
@@ -215,7 +215,7 @@ public abstract class HTTP2StreamEndPoint implements EndPoint
private int fillFromData(Stream.Data data, ByteBuffer sink)
{
int length = 0;
- ByteBuffer source = data.frame().getData();
+ ByteBuffer source = data.frame().getByteBuffer();
boolean hasContent = source.hasRemaining();
if (hasContent)
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/DataGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/DataGenerator.java
index 5de967599a5..bd13aa83ee3 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/DataGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/DataGenerator.java
@@ -19,7 +19,8 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class DataGenerator
@@ -31,12 +32,12 @@ public class DataGenerator
this.headerGenerator = headerGenerator;
}
- public int generate(ByteBufferPool.Lease lease, DataFrame frame, int maxLength)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, DataFrame frame, int maxLength)
{
- return generateData(lease, frame.getStreamId(), frame.getData(), frame.isEndStream(), maxLength);
+ return generateData(accumulator, frame.getStreamId(), frame.getByteBuffer(), frame.isEndStream(), maxLength);
}
- public int generateData(ByteBufferPool.Lease lease, int streamId, ByteBuffer data, boolean last, int maxLength)
+ public int generateData(RetainableByteBufferPool.Accumulator accumulator, int streamId, ByteBuffer data, boolean last, int maxLength)
{
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
@@ -46,7 +47,7 @@ public class DataGenerator
int length = Math.min(dataLength, Math.min(maxFrameSize, maxLength));
if (length == dataLength)
{
- generateFrame(lease, streamId, data, last);
+ generateFrame(accumulator, streamId, data, last);
}
else
{
@@ -56,12 +57,12 @@ public class DataGenerator
ByteBuffer slice = data.slice();
data.position(newLimit);
data.limit(limit);
- generateFrame(lease, streamId, slice, false);
+ generateFrame(accumulator, streamId, slice, false);
}
return Frame.HEADER_LENGTH + length;
}
- private void generateFrame(ByteBufferPool.Lease lease, int streamId, ByteBuffer data, boolean last)
+ private void generateFrame(RetainableByteBufferPool.Accumulator accumulator, int streamId, ByteBuffer data, boolean last)
{
int length = data.remaining();
@@ -69,11 +70,11 @@ public class DataGenerator
if (last)
flags |= Flags.END_STREAM;
- ByteBuffer header = headerGenerator.generate(lease, FrameType.DATA, Frame.HEADER_LENGTH + length, length, flags, streamId);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ RetainableByteBuffer header = headerGenerator.generate(FrameType.DATA, Frame.HEADER_LENGTH + length, length, flags, streamId);
+ BufferUtil.flipToFlush(header.getByteBuffer(), 0);
+ accumulator.append(header);
// Skip empty data buffers.
if (data.remaining() > 0)
- lease.append(data, false);
+ accumulator.append(RetainableByteBuffer.wrap(data));
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/FrameGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/FrameGenerator.java
index 0c0b6bfe4b1..0386b0a5b2c 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/FrameGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/FrameGenerator.java
@@ -20,7 +20,9 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.HpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public abstract class FrameGenerator
{
@@ -31,11 +33,11 @@ public abstract class FrameGenerator
this.headerGenerator = headerGenerator;
}
- public abstract int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException;
+ public abstract int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame) throws HpackException;
- protected ByteBuffer generateHeader(ByteBufferPool.Lease lease, FrameType frameType, int length, int flags, int streamId)
+ protected RetainableByteBuffer generateHeader(FrameType frameType, int length, int flags, int streamId)
{
- return headerGenerator.generate(lease, frameType, Frame.HEADER_LENGTH + length, length, flags, streamId);
+ return headerGenerator.generate(frameType, Frame.HEADER_LENGTH + length, length, flags, streamId);
}
public int getMaxFrameSize()
@@ -48,17 +50,19 @@ public abstract class FrameGenerator
return headerGenerator.isUseDirectByteBuffers();
}
- protected ByteBuffer encode(HpackEncoder encoder, ByteBufferPool.Lease lease, MetaData metaData, int maxFrameSize) throws HpackException
+ protected RetainableByteBuffer encode(HpackEncoder encoder, MetaData metaData, int maxFrameSize) throws HpackException
{
- ByteBuffer hpacked = lease.acquire(maxFrameSize, isUseDirectByteBuffers());
+ RetainableByteBuffer hpacked = headerGenerator.getRetainableByteBufferPool().acquire(maxFrameSize, isUseDirectByteBuffers());
try
{
- encoder.encode(hpacked, metaData);
+ ByteBuffer byteBuffer = hpacked.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ encoder.encode(byteBuffer, metaData);
return hpacked;
}
catch (HpackException x)
{
- lease.release(hpacked);
+ hpacked.release();
throw x;
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/Generator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/Generator.java
index aa7d3928125..86ba49cb5f3 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/Generator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/Generator.java
@@ -18,31 +18,31 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.HpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class Generator
{
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final HeaderGenerator headerGenerator;
private final HpackEncoder hpackEncoder;
private final FrameGenerator[] generators;
private final DataGenerator dataGenerator;
- public Generator(ByteBufferPool byteBufferPool)
+ public Generator(RetainableByteBufferPool bufferPool)
{
- this(byteBufferPool, 4096, 0);
+ this(bufferPool, 4096, 0);
}
- public Generator(ByteBufferPool byteBufferPool, int maxDynamicTableSize, int maxHeaderBlockFragment)
+ public Generator(RetainableByteBufferPool bufferPool, int maxDynamicTableSize, int maxHeaderBlockFragment)
{
- this(byteBufferPool, true, maxDynamicTableSize, maxHeaderBlockFragment);
+ this(bufferPool, true, maxDynamicTableSize, maxHeaderBlockFragment);
}
- public Generator(ByteBufferPool byteBufferPool, boolean useDirectByteBuffers, int maxDynamicTableSize, int maxHeaderBlockFragment)
+ public Generator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers, int maxDynamicTableSize, int maxHeaderBlockFragment)
{
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
- headerGenerator = new HeaderGenerator(useDirectByteBuffers);
+ headerGenerator = new HeaderGenerator(bufferPool, useDirectByteBuffers);
hpackEncoder = new HpackEncoder(maxDynamicTableSize);
this.generators = new FrameGenerator[FrameType.values().length];
@@ -61,9 +61,9 @@ public class Generator
this.dataGenerator = new DataGenerator(headerGenerator);
}
- public ByteBufferPool getByteBufferPool()
+ public RetainableByteBufferPool getRetainableByteBufferPool()
{
- return byteBufferPool;
+ return bufferPool;
}
public void setValidateHpackEncoding(boolean validateEncoding)
@@ -81,14 +81,14 @@ public class Generator
headerGenerator.setMaxFrameSize(maxFrameSize);
}
- public int control(ByteBufferPool.Lease lease, Frame frame) throws HpackException
+ public int control(RetainableByteBufferPool.Accumulator accumulator, Frame frame) throws HpackException
{
- return generators[frame.getType().getType()].generate(lease, frame);
+ return generators[frame.getType().getType()].generate(accumulator, frame);
}
- public int data(ByteBufferPool.Lease lease, DataFrame frame, int maxLength)
+ public int data(RetainableByteBufferPool.Accumulator accumulator, DataFrame frame, int maxLength)
{
- return dataGenerator.generate(lease, frame, maxLength);
+ return dataGenerator.generate(accumulator, frame, maxLength);
}
public void setMaxHeaderListSize(int value)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/GoAwayGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/GoAwayGenerator.java
index 8468d29db22..5f3b6d3ec93 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/GoAwayGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/GoAwayGenerator.java
@@ -20,7 +20,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.GoAwayFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class GoAwayGenerator extends FrameGenerator
@@ -31,13 +32,13 @@ public class GoAwayGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
GoAwayFrame goAwayFrame = (GoAwayFrame)frame;
- return generateGoAway(lease, goAwayFrame.getLastStreamId(), goAwayFrame.getError(), goAwayFrame.getPayload());
+ return generateGoAway(accumulator, goAwayFrame.getLastStreamId(), goAwayFrame.getError(), goAwayFrame.getPayload());
}
- public int generateGoAway(ByteBufferPool.Lease lease, int lastStreamId, int error, byte[] payload)
+ public int generateGoAway(RetainableByteBufferPool.Accumulator accumulator, int lastStreamId, int error, byte[] payload)
{
if (lastStreamId < 0)
lastStreamId = 0;
@@ -51,16 +52,17 @@ public class GoAwayGenerator extends FrameGenerator
payload = Arrays.copyOfRange(payload, 0, maxPayloadLength);
int length = fixedLength + (payload != null ? payload.length : 0);
- ByteBuffer header = generateHeader(lease, FrameType.GO_AWAY, length, Flags.NONE, 0);
+ RetainableByteBuffer header = generateHeader(FrameType.GO_AWAY, length, Flags.NONE, 0);
+ ByteBuffer byteBuffer = header.getByteBuffer();
- header.putInt(lastStreamId);
- header.putInt(error);
+ byteBuffer.putInt(lastStreamId);
+ byteBuffer.putInt(error);
if (payload != null)
- header.put(payload);
+ byteBuffer.put(payload);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + length;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeaderGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeaderGenerator.java
index 1d1592c19e9..ccdebbdd907 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeaderGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeaderGenerator.java
@@ -17,38 +17,49 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public class HeaderGenerator
{
private int maxFrameSize = Frame.DEFAULT_MAX_LENGTH;
+ private final RetainableByteBufferPool bufferPool;
private final boolean useDirectByteBuffers;
- public HeaderGenerator()
+ public HeaderGenerator(RetainableByteBufferPool bufferPool)
{
- this(true);
+ this(bufferPool, true);
}
- public HeaderGenerator(boolean useDirectByteBuffers)
+ public HeaderGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
+ this.bufferPool = bufferPool;
this.useDirectByteBuffers = useDirectByteBuffers;
}
+ public RetainableByteBufferPool getRetainableByteBufferPool()
+ {
+ return bufferPool;
+ }
+
public boolean isUseDirectByteBuffers()
{
return useDirectByteBuffers;
}
- public ByteBuffer generate(ByteBufferPool.Lease lease, FrameType frameType, int capacity, int length, int flags, int streamId)
+ public RetainableByteBuffer generate(FrameType frameType, int capacity, int length, int flags, int streamId)
{
- ByteBuffer header = lease.acquire(capacity, isUseDirectByteBuffers());
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(capacity, isUseDirectByteBuffers());
+ ByteBuffer header = buffer.getByteBuffer();
+ BufferUtil.clearToFill(header);
header.put((byte)((length & 0x00_FF_00_00) >>> 16));
header.put((byte)((length & 0x00_00_FF_00) >>> 8));
header.put((byte)((length & 0x00_00_00_FF)));
header.put((byte)frameType.getType());
header.put((byte)flags);
header.putInt(streamId);
- return header;
+ return buffer;
}
public int getMaxFrameSize()
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeadersGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeadersGenerator.java
index c1afa0a46ee..57d9dcd4443 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeadersGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/HeadersGenerator.java
@@ -23,7 +23,8 @@ import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.HpackException;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class HeadersGenerator extends FrameGenerator
@@ -46,13 +47,13 @@ public class HeadersGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame) throws HpackException
{
HeadersFrame headersFrame = (HeadersFrame)frame;
- return generateHeaders(lease, headersFrame.getStreamId(), headersFrame.getMetaData(), headersFrame.getPriority(), headersFrame.isEndStream());
+ return generateHeaders(accumulator, headersFrame.getStreamId(), headersFrame.getMetaData(), headersFrame.getPriority(), headersFrame.isEndStream());
}
- public int generateHeaders(ByteBufferPool.Lease lease, int streamId, MetaData metaData, PriorityFrame priority, boolean endStream) throws HpackException
+ public int generateHeaders(RetainableByteBufferPool.Accumulator accumulator, int streamId, MetaData metaData, PriorityFrame priority, boolean endStream) throws HpackException
{
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
@@ -62,12 +63,13 @@ public class HeadersGenerator extends FrameGenerator
if (priority != null)
flags = Flags.PRIORITY;
- ByteBuffer hpacked = encode(encoder, lease, metaData, getMaxFrameSize());
- int hpackedLength = hpacked.position();
- BufferUtil.flipToFlush(hpacked, 0);
+ RetainableByteBuffer hpack = encode(encoder, metaData, getMaxFrameSize());
+ ByteBuffer hpackByteBuffer = hpack.getByteBuffer();
+ int hpackLength = hpackByteBuffer.position();
+ BufferUtil.flipToFlush(hpackByteBuffer, 0);
// Split into CONTINUATION frames if necessary.
- if (maxHeaderBlockFragment > 0 && hpackedLength > maxHeaderBlockFragment)
+ if (maxHeaderBlockFragment > 0 && hpackLength > maxHeaderBlockFragment)
{
if (endStream)
flags |= Flags.END_STREAM;
@@ -76,35 +78,38 @@ public class HeadersGenerator extends FrameGenerator
if (priority != null)
length += PriorityFrame.PRIORITY_LENGTH;
- ByteBuffer header = generateHeader(lease, FrameType.HEADERS, length, flags, streamId);
- generatePriority(header, priority);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
- hpacked.limit(maxHeaderBlockFragment);
- lease.append(hpacked.slice(), false);
+ RetainableByteBuffer header = generateHeader(FrameType.HEADERS, length, flags, streamId);
+ ByteBuffer headerByteBuffer = header.getByteBuffer();
+ generatePriority(headerByteBuffer, priority);
+ BufferUtil.flipToFlush(headerByteBuffer, 0);
+ accumulator.append(header);
+ hpackByteBuffer.limit(maxHeaderBlockFragment);
+ accumulator.append(RetainableByteBuffer.wrap(hpackByteBuffer.slice()));
int totalLength = Frame.HEADER_LENGTH + length;
int position = maxHeaderBlockFragment;
int limit = position + maxHeaderBlockFragment;
- while (limit < hpackedLength)
+ while (limit < hpackLength)
{
- hpacked.position(position).limit(limit);
- header = generateHeader(lease, FrameType.CONTINUATION, maxHeaderBlockFragment, Flags.NONE, streamId);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
- lease.append(hpacked.slice(), false);
+ hpackByteBuffer.position(position).limit(limit);
+ header = generateHeader(FrameType.CONTINUATION, maxHeaderBlockFragment, Flags.NONE, streamId);
+ headerByteBuffer = header.getByteBuffer();
+ BufferUtil.flipToFlush(headerByteBuffer, 0);
+ accumulator.append(header);
+ accumulator.append(RetainableByteBuffer.wrap(hpackByteBuffer.slice()));
position += maxHeaderBlockFragment;
limit += maxHeaderBlockFragment;
totalLength += Frame.HEADER_LENGTH + maxHeaderBlockFragment;
}
- hpacked.position(position).limit(hpackedLength);
- header = generateHeader(lease, FrameType.CONTINUATION, hpacked.remaining(), Flags.END_HEADERS, streamId);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
- lease.append(hpacked, true);
- totalLength += Frame.HEADER_LENGTH + hpacked.remaining();
+ hpackByteBuffer.position(position).limit(hpackLength);
+ header = generateHeader(FrameType.CONTINUATION, hpack.remaining(), Flags.END_HEADERS, streamId);
+ headerByteBuffer = header.getByteBuffer();
+ BufferUtil.flipToFlush(headerByteBuffer, 0);
+ accumulator.append(header);
+ accumulator.append(hpack);
+ totalLength += Frame.HEADER_LENGTH + hpack.remaining();
return totalLength;
}
@@ -114,15 +119,16 @@ public class HeadersGenerator extends FrameGenerator
if (endStream)
flags |= Flags.END_STREAM;
- int length = hpackedLength;
+ int length = hpackLength;
if (priority != null)
length += PriorityFrame.PRIORITY_LENGTH;
- ByteBuffer header = generateHeader(lease, FrameType.HEADERS, length, flags, streamId);
- generatePriority(header, priority);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
- lease.append(hpacked, true);
+ RetainableByteBuffer header = generateHeader(FrameType.HEADERS, length, flags, streamId);
+ ByteBuffer headerByteBuffer = header.getByteBuffer();
+ generatePriority(headerByteBuffer, priority);
+ BufferUtil.flipToFlush(headerByteBuffer, 0);
+ accumulator.append(header);
+ accumulator.append(hpack);
return Frame.HEADER_LENGTH + length;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/NoOpGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/NoOpGenerator.java
index 388bb582cbc..0361b466dc9 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/NoOpGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/NoOpGenerator.java
@@ -14,7 +14,7 @@
package org.eclipse.jetty.http2.internal.generator;
import org.eclipse.jetty.http2.frames.Frame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class NoOpGenerator extends FrameGenerator
{
@@ -24,7 +24,7 @@ public class NoOpGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
return 0;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PingGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PingGenerator.java
index fd12c31433d..9299aa77168 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PingGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PingGenerator.java
@@ -19,7 +19,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.PingFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class PingGenerator extends FrameGenerator
@@ -30,23 +31,24 @@ public class PingGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
PingFrame pingFrame = (PingFrame)frame;
- return generatePing(lease, pingFrame.getPayload(), pingFrame.isReply());
+ return generatePing(accumulator, pingFrame.getPayload(), pingFrame.isReply());
}
- public int generatePing(ByteBufferPool.Lease lease, byte[] payload, boolean reply)
+ public int generatePing(RetainableByteBufferPool.Accumulator accumulator, byte[] payload, boolean reply)
{
if (payload.length != PingFrame.PING_LENGTH)
throw new IllegalArgumentException("Invalid payload length: " + payload.length);
- ByteBuffer header = generateHeader(lease, FrameType.PING, PingFrame.PING_LENGTH, reply ? Flags.ACK : Flags.NONE, 0);
+ RetainableByteBuffer header = generateHeader(FrameType.PING, PingFrame.PING_LENGTH, reply ? Flags.ACK : Flags.NONE, 0);
+ ByteBuffer byteBuffer = header.getByteBuffer();
- header.put(payload);
+ byteBuffer.put(payload);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + PingFrame.PING_LENGTH;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PrefaceGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PrefaceGenerator.java
index b2cddd59286..941ab927073 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PrefaceGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PrefaceGenerator.java
@@ -17,7 +17,8 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.PrefaceFrame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class PrefaceGenerator extends FrameGenerator
{
@@ -27,9 +28,9 @@ public class PrefaceGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
- lease.append(ByteBuffer.wrap(PrefaceFrame.PREFACE_BYTES), false);
+ accumulator.append(RetainableByteBuffer.wrap(ByteBuffer.wrap(PrefaceFrame.PREFACE_BYTES)));
return PrefaceFrame.PREFACE_BYTES.length;
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PriorityGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PriorityGenerator.java
index 8ddb988de0c..707052a007c 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PriorityGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PriorityGenerator.java
@@ -19,7 +19,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.PriorityFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class PriorityGenerator extends FrameGenerator
@@ -30,18 +31,19 @@ public class PriorityGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
PriorityFrame priorityFrame = (PriorityFrame)frame;
- return generatePriority(lease, priorityFrame.getStreamId(), priorityFrame.getParentStreamId(), priorityFrame.getWeight(), priorityFrame.isExclusive());
+ return generatePriority(accumulator, priorityFrame.getStreamId(), priorityFrame.getParentStreamId(), priorityFrame.getWeight(), priorityFrame.isExclusive());
}
- public int generatePriority(ByteBufferPool.Lease lease, int streamId, int parentStreamId, int weight, boolean exclusive)
+ public int generatePriority(RetainableByteBufferPool.Accumulator accumulator, int streamId, int parentStreamId, int weight, boolean exclusive)
{
- ByteBuffer header = generateHeader(lease, FrameType.PRIORITY, PriorityFrame.PRIORITY_LENGTH, Flags.NONE, streamId);
- generatePriorityBody(header, streamId, parentStreamId, weight, exclusive);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ RetainableByteBuffer header = generateHeader(FrameType.PRIORITY, PriorityFrame.PRIORITY_LENGTH, Flags.NONE, streamId);
+ ByteBuffer byteBuffer = header.getByteBuffer();
+ generatePriorityBody(byteBuffer, streamId, parentStreamId, weight, exclusive);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + PriorityFrame.PRIORITY_LENGTH;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PushPromiseGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PushPromiseGenerator.java
index a100a5d173a..230cb8fbf8a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PushPromiseGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/PushPromiseGenerator.java
@@ -22,7 +22,8 @@ import org.eclipse.jetty.http2.frames.PushPromiseFrame;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.hpack.HpackException;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class PushPromiseGenerator extends FrameGenerator
@@ -36,13 +37,13 @@ public class PushPromiseGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame) throws HpackException
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame) throws HpackException
{
PushPromiseFrame pushPromiseFrame = (PushPromiseFrame)frame;
- return generatePushPromise(lease, pushPromiseFrame.getStreamId(), pushPromiseFrame.getPromisedStreamId(), pushPromiseFrame.getMetaData());
+ return generatePushPromise(accumulator, pushPromiseFrame.getStreamId(), pushPromiseFrame.getPromisedStreamId(), pushPromiseFrame.getMetaData());
}
- public int generatePushPromise(ByteBufferPool.Lease lease, int streamId, int promisedStreamId, MetaData metaData) throws HpackException
+ public int generatePushPromise(RetainableByteBufferPool.Accumulator accumulator, int streamId, int promisedStreamId, MetaData metaData) throws HpackException
{
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
@@ -54,19 +55,21 @@ public class PushPromiseGenerator extends FrameGenerator
int extraSpace = 4;
maxFrameSize -= extraSpace;
- ByteBuffer hpacked = encode(encoder, lease, metaData, maxFrameSize);
- int hpackedLength = hpacked.position();
- BufferUtil.flipToFlush(hpacked, 0);
+ RetainableByteBuffer hpack = encode(encoder, metaData, maxFrameSize);
+ ByteBuffer hpackByteBuffer = hpack.getByteBuffer();
+ int hpackLength = hpackByteBuffer.position();
+ BufferUtil.flipToFlush(hpackByteBuffer, 0);
- int length = hpackedLength + extraSpace;
+ int length = hpackLength + extraSpace;
int flags = Flags.END_HEADERS;
- ByteBuffer header = generateHeader(lease, FrameType.PUSH_PROMISE, length, flags, streamId);
- header.putInt(promisedStreamId);
- BufferUtil.flipToFlush(header, 0);
+ RetainableByteBuffer header = generateHeader(FrameType.PUSH_PROMISE, length, flags, streamId);
+ ByteBuffer headerByteBuffer = header.getByteBuffer();
+ headerByteBuffer.putInt(promisedStreamId);
+ BufferUtil.flipToFlush(headerByteBuffer, 0);
- lease.append(header, true);
- lease.append(hpacked, true);
+ accumulator.append(header);
+ accumulator.append(hpack);
return Frame.HEADER_LENGTH + length;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/ResetGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/ResetGenerator.java
index ed55d23d5cd..df8960c54f2 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/ResetGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/ResetGenerator.java
@@ -19,7 +19,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class ResetGenerator extends FrameGenerator
@@ -30,21 +31,22 @@ public class ResetGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
ResetFrame resetFrame = (ResetFrame)frame;
- return generateReset(lease, resetFrame.getStreamId(), resetFrame.getError());
+ return generateReset(accumulator, resetFrame.getStreamId(), resetFrame.getError());
}
- public int generateReset(ByteBufferPool.Lease lease, int streamId, int error)
+ public int generateReset(RetainableByteBufferPool.Accumulator accumulator, int streamId, int error)
{
if (streamId < 0)
throw new IllegalArgumentException("Invalid stream id: " + streamId);
- ByteBuffer header = generateHeader(lease, FrameType.RST_STREAM, ResetFrame.RESET_LENGTH, Flags.NONE, streamId);
- header.putInt(error);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ RetainableByteBuffer header = generateHeader(FrameType.RST_STREAM, ResetFrame.RESET_LENGTH, Flags.NONE, streamId);
+ ByteBuffer byteBuffer = header.getByteBuffer();
+ byteBuffer.putInt(error);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + ResetFrame.RESET_LENGTH;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/SettingsGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/SettingsGenerator.java
index e31fe3f5756..ddbee07a498 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/SettingsGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/SettingsGenerator.java
@@ -20,7 +20,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class SettingsGenerator extends FrameGenerator
@@ -31,13 +32,13 @@ public class SettingsGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
SettingsFrame settingsFrame = (SettingsFrame)frame;
- return generateSettings(lease, settingsFrame.getSettings(), settingsFrame.isReply());
+ return generateSettings(accumulator, settingsFrame.getSettings(), settingsFrame.isReply());
}
- public int generateSettings(ByteBufferPool.Lease lease, Map settings, boolean reply)
+ public int generateSettings(RetainableByteBufferPool.Accumulator accumulator, Map settings, boolean reply)
{
// Two bytes for the identifier, four bytes for the value.
int entryLength = 2 + 4;
@@ -45,16 +46,17 @@ public class SettingsGenerator extends FrameGenerator
if (length > getMaxFrameSize())
throw new IllegalArgumentException("Invalid settings, too big");
- ByteBuffer header = generateHeader(lease, FrameType.SETTINGS, length, reply ? Flags.ACK : Flags.NONE, 0);
+ RetainableByteBuffer header = generateHeader(FrameType.SETTINGS, length, reply ? Flags.ACK : Flags.NONE, 0);
+ ByteBuffer byteBuffer = header.getByteBuffer();
for (Map.Entry entry : settings.entrySet())
{
- header.putShort(entry.getKey().shortValue());
- header.putInt(entry.getValue());
+ byteBuffer.putShort(entry.getKey().shortValue());
+ byteBuffer.putInt(entry.getValue());
}
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + length;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/WindowUpdateGenerator.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/WindowUpdateGenerator.java
index 960dcd20bb9..d2012ef1eed 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/WindowUpdateGenerator.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/generator/WindowUpdateGenerator.java
@@ -19,7 +19,8 @@ import org.eclipse.jetty.http2.frames.Frame;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class WindowUpdateGenerator extends FrameGenerator
@@ -30,21 +31,22 @@ public class WindowUpdateGenerator extends FrameGenerator
}
@Override
- public int generate(ByteBufferPool.Lease lease, Frame frame)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, Frame frame)
{
WindowUpdateFrame windowUpdateFrame = (WindowUpdateFrame)frame;
- return generateWindowUpdate(lease, windowUpdateFrame.getStreamId(), windowUpdateFrame.getWindowDelta());
+ return generateWindowUpdate(accumulator, windowUpdateFrame.getStreamId(), windowUpdateFrame.getWindowDelta());
}
- public int generateWindowUpdate(ByteBufferPool.Lease lease, int streamId, int windowUpdate)
+ public int generateWindowUpdate(RetainableByteBufferPool.Accumulator accumulator, int streamId, int windowUpdate)
{
if (windowUpdate < 0)
throw new IllegalArgumentException("Invalid window update: " + windowUpdate);
- ByteBuffer header = generateHeader(lease, FrameType.WINDOW_UPDATE, WindowUpdateFrame.WINDOW_UPDATE_LENGTH, Flags.NONE, streamId);
- header.putInt(windowUpdate);
- BufferUtil.flipToFlush(header, 0);
- lease.append(header, true);
+ RetainableByteBuffer header = generateHeader(FrameType.WINDOW_UPDATE, WindowUpdateFrame.WINDOW_UPDATE_LENGTH, Flags.NONE, streamId);
+ ByteBuffer byteBuffer = header.getByteBuffer();
+ byteBuffer.putInt(windowUpdate);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(header);
return Frame.HEADER_LENGTH + WindowUpdateFrame.WINDOW_UPDATE_LENGTH;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ContinuationBodyParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ContinuationBodyParser.java
index 7ec64d869b7..5315b8ce67a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ContinuationBodyParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ContinuationBodyParser.java
@@ -20,6 +20,7 @@ import org.eclipse.jetty.http2.frames.ContinuationFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.Flags;
+import org.eclipse.jetty.io.RetainableByteBuffer;
public class ContinuationBodyParser extends BodyParser
{
@@ -100,9 +101,9 @@ public class ContinuationBodyParser extends BodyParser
private boolean onHeaders(ByteBuffer buffer)
{
- ByteBuffer headerBlock = headerBlockFragments.complete();
- MetaData metaData = headerBlockParser.parse(headerBlock, headerBlock.remaining());
- headerBlockFragments.getByteBufferPool().release(headerBlock);
+ RetainableByteBuffer headerBlock = headerBlockFragments.complete();
+ MetaData metaData = headerBlockParser.parse(headerBlock.getByteBuffer(), headerBlock.remaining());
+ headerBlock.release();
if (metaData == null)
return true;
if (metaData == HeaderBlockParser.SESSION_FAILURE)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockFragments.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockFragments.java
index 8e4e892002c..e247606a0a3 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockFragments.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockFragments.java
@@ -16,24 +16,21 @@ package org.eclipse.jetty.http2.internal.parser;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http2.frames.PriorityFrame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public class HeaderBlockFragments
{
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private PriorityFrame priorityFrame;
private boolean endStream;
private int streamId;
- private ByteBuffer storage;
+ private RetainableByteBuffer storage;
- public HeaderBlockFragments(ByteBufferPool byteBufferPool)
+ public HeaderBlockFragments(RetainableByteBufferPool bufferPool)
{
- this.byteBufferPool = byteBufferPool;
- }
-
- public ByteBufferPool getByteBufferPool()
- {
- return byteBufferPool;
+ this.bufferPool = bufferPool;
}
public void storeFragment(ByteBuffer fragment, int length, boolean last)
@@ -41,27 +38,28 @@ public class HeaderBlockFragments
if (storage == null)
{
int space = last ? length : length * 2;
- storage = byteBufferPool.acquire(space, fragment.isDirect());
- storage.clear();
+ storage = bufferPool.acquire(space, fragment.isDirect());
+ BufferUtil.flipToFill(storage.getByteBuffer());
}
// Grow the storage if necessary.
if (storage.remaining() < length)
{
+ ByteBuffer byteBuffer = storage.getByteBuffer();
int space = last ? length : length * 2;
- int capacity = storage.position() + space;
- ByteBuffer newStorage = byteBufferPool.acquire(capacity, storage.isDirect());
- newStorage.clear();
- storage.flip();
- newStorage.put(storage);
- byteBufferPool.release(storage);
+ int capacity = byteBuffer.position() + space;
+ RetainableByteBuffer newStorage = bufferPool.acquire(capacity, storage.isDirect());
+ BufferUtil.flipToFill(newStorage.getByteBuffer());
+ byteBuffer.flip();
+ newStorage.getByteBuffer().put(byteBuffer);
+ storage.release();
storage = newStorage;
}
// Copy the fragment into the storage.
int limit = fragment.limit();
fragment.limit(fragment.position() + length);
- storage.put(fragment);
+ storage.getByteBuffer().put(fragment);
fragment.limit(limit);
}
@@ -85,11 +83,11 @@ public class HeaderBlockFragments
this.endStream = endStream;
}
- public ByteBuffer complete()
+ public RetainableByteBuffer complete()
{
- ByteBuffer result = storage;
+ RetainableByteBuffer result = storage;
storage = null;
- result.flip();
+ result.getByteBuffer().flip();
return result;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockParser.java
index 8ab18235422..2c8baf850a8 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/HeaderBlockParser.java
@@ -20,7 +20,8 @@ import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.http2.hpack.HpackException;
import org.eclipse.jetty.http2.internal.ErrorCode;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -32,15 +33,15 @@ public class HeaderBlockParser
private static final Logger LOG = LoggerFactory.getLogger(HeaderBlockParser.class);
private final HeaderParser headerParser;
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final HpackDecoder hpackDecoder;
private final BodyParser notifier;
- private ByteBuffer blockBuffer;
+ private RetainableByteBuffer blockBuffer;
- public HeaderBlockParser(HeaderParser headerParser, ByteBufferPool byteBufferPool, HpackDecoder hpackDecoder, BodyParser notifier)
+ public HeaderBlockParser(HeaderParser headerParser, RetainableByteBufferPool bufferPool, HpackDecoder hpackDecoder, BodyParser notifier)
{
this.headerParser = headerParser;
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
this.hpackDecoder = hpackDecoder;
this.notifier = notifier;
}
@@ -61,17 +62,19 @@ public class HeaderBlockParser
// If they are not all available, accumulate them.
// When all are available, decode them.
- int accumulated = blockBuffer == null ? 0 : blockBuffer.position();
+ ByteBuffer byteBuffer = blockBuffer == null ? null : blockBuffer.getByteBuffer();
+ int accumulated = byteBuffer == null ? 0 : byteBuffer.position();
int remaining = blockLength - accumulated;
if (buffer.remaining() < remaining)
{
if (blockBuffer == null)
{
- blockBuffer = byteBufferPool.acquire(blockLength, buffer.isDirect());
- BufferUtil.clearToFill(blockBuffer);
+ blockBuffer = bufferPool.acquire(blockLength, buffer.isDirect());
+ byteBuffer = blockBuffer.getByteBuffer();
+ BufferUtil.flipToFill(byteBuffer);
}
- blockBuffer.put(buffer);
+ byteBuffer.put(buffer);
return null;
}
else
@@ -79,11 +82,11 @@ public class HeaderBlockParser
int limit = buffer.limit();
buffer.limit(buffer.position() + remaining);
ByteBuffer toDecode;
- if (blockBuffer != null)
+ if (byteBuffer != null)
{
- blockBuffer.put(buffer);
- BufferUtil.flipToFlush(blockBuffer, 0);
- toDecode = blockBuffer;
+ byteBuffer.put(buffer);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ toDecode = byteBuffer;
}
else
{
@@ -121,7 +124,7 @@ public class HeaderBlockParser
if (blockBuffer != null)
{
- byteBufferPool.release(blockBuffer);
+ blockBuffer.release();
blockBuffer = null;
}
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/Parser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/Parser.java
index e5fd3fd74a1..9e616da7b61 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/Parser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/Parser.java
@@ -31,7 +31,7 @@ import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
import org.eclipse.jetty.http2.hpack.HpackDecoder;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,7 +44,7 @@ public class Parser
{
private static final Logger LOG = LoggerFactory.getLogger(Parser.class);
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final Listener listener;
private final HeaderParser headerParser;
private final HpackDecoder hpackDecoder;
@@ -55,14 +55,14 @@ public class Parser
private boolean continuation;
private State state = State.HEADER;
- public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize)
+ public Parser(RetainableByteBufferPool bufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize)
{
- this(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, RateControl.NO_RATE_CONTROL);
+ this(bufferPool, listener, maxDynamicTableSize, maxHeaderSize, RateControl.NO_RATE_CONTROL);
}
- public Parser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl)
+ public Parser(RetainableByteBufferPool bufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl)
{
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
this.listener = listener;
this.headerParser = new HeaderParser(rateControl == null ? RateControl.NO_RATE_CONTROL : rateControl);
this.hpackDecoder = new HpackDecoder(maxDynamicTableSize, maxHeaderSize);
@@ -73,8 +73,8 @@ public class Parser
{
Listener listener = wrapper.apply(this.listener);
unknownBodyParser = new UnknownBodyParser(headerParser, listener);
- HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, byteBufferPool, hpackDecoder, unknownBodyParser);
- HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(byteBufferPool);
+ HeaderBlockParser headerBlockParser = new HeaderBlockParser(headerParser, bufferPool, hpackDecoder, unknownBodyParser);
+ HeaderBlockFragments headerBlockFragments = new HeaderBlockFragments(bufferPool);
bodyParsers[FrameType.DATA.getType()] = new DataBodyParser(headerParser, listener);
bodyParsers[FrameType.HEADERS.getType()] = new HeadersBodyParser(headerParser, listener, headerBlockParser, headerBlockFragments);
bodyParsers[FrameType.PRIORITY.getType()] = new PriorityBodyParser(headerParser, listener);
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ServerParser.java b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ServerParser.java
index d7dbfa98095..8023fd4a8a4 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ServerParser.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/main/java/org/eclipse/jetty/http2/internal/parser/ServerParser.java
@@ -19,7 +19,7 @@ import org.eclipse.jetty.http2.RateControl;
import org.eclipse.jetty.http2.frames.FrameType;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.Flags;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,9 +33,9 @@ public class ServerParser extends Parser
private State state = State.PREFACE;
private boolean notifyPreface = true;
- public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl)
+ public ServerParser(RetainableByteBufferPool bufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize, RateControl rateControl)
{
- super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize, rateControl);
+ super(bufferPool, listener, maxDynamicTableSize, maxHeaderSize, rateControl);
this.listener = listener;
this.prefaceParser = new PrefaceParser(listener);
}
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java
index 1c68695415c..e8d691a978f 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ContinuationParseTest.java
@@ -29,8 +29,8 @@ import org.eclipse.jetty.http2.internal.Flags;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.HeadersGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -42,11 +42,11 @@ public class ContinuationParseTest
@Test
public void testParseOneByteAtATime() throws Exception
{
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder());
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -71,10 +71,10 @@ public class ContinuationParseTest
.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields, -1);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateHeaders(lease, streamId, metaData, null, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateHeaders(accumulator, streamId, metaData, null, true);
- List byteBuffers = lease.getByteBuffers();
+ List byteBuffers = accumulator.getByteBuffers();
assertEquals(2, byteBuffers.size());
ByteBuffer headersBody = byteBuffers.remove(1);
@@ -131,7 +131,7 @@ public class ContinuationParseTest
byteBuffers.add(headersBody.slice());
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java
index 23f17926dc6..e0da7e4a542 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/DataGenerateParseTest.java
@@ -22,8 +22,8 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.DataGenerator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.Test;
@@ -34,7 +34,7 @@ public class DataGenerateParseTest
{
private final byte[] smallContent = new byte[128];
private final byte[] largeContent = new byte[128 * 1024];
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
public DataGenerateParseTest()
{
@@ -62,7 +62,7 @@ public class DataGenerateParseTest
DataFrame frame = frames.get(0);
assertTrue(frame.getStreamId() != 0);
assertTrue(frame.isEndStream());
- assertEquals(content, frame.getData());
+ assertEquals(content, frame.getByteBuffer());
}
@Test
@@ -77,7 +77,7 @@ public class DataGenerateParseTest
DataFrame frame = frames.get(i - 1);
assertTrue(frame.getStreamId() != 0);
assertEquals(i == frames.size(), frame.isEndStream());
- aggregate.put(frame.getData());
+ aggregate.put(frame.getByteBuffer());
}
aggregate.flip();
assertEquals(content, aggregate);
@@ -85,10 +85,10 @@ public class DataGenerateParseTest
private List testGenerateParse(ByteBuffer data)
{
- DataGenerator generator = new DataGenerator(new HeaderGenerator());
+ DataGenerator generator = new DataGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onData(DataFrame frame)
@@ -101,19 +101,19 @@ public class DataGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
ByteBuffer slice = data.slice();
int generated = 0;
while (true)
{
- generated += generator.generateData(lease, 13, slice, true, slice.remaining());
+ generated += generator.generateData(accumulator, 13, slice, true, slice.remaining());
generated -= Frame.HEADER_LENGTH;
if (generated == data.remaining())
break;
}
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
}
@@ -125,10 +125,10 @@ public class DataGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime()
{
- DataGenerator generator = new DataGenerator(new HeaderGenerator());
+ DataGenerator generator = new DataGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onData(DataFrame frame)
@@ -141,20 +141,20 @@ public class DataGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
ByteBuffer data = ByteBuffer.wrap(largeContent);
ByteBuffer slice = data.slice();
int generated = 0;
while (true)
{
- generated += generator.generateData(lease, 13, slice, true, slice.remaining());
+ generated += generator.generateData(accumulator, 13, slice, true, slice.remaining());
generated -= Frame.HEADER_LENGTH;
if (generated == data.remaining())
break;
}
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java
index b52e9e35e52..47b80c64c6a 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/FrameFloodTest.java
@@ -24,8 +24,8 @@ import org.eclipse.jetty.http2.WindowRateControl;
import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.internal.Flags;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -33,7 +33,7 @@ import static org.hamcrest.Matchers.lessThan;
public class FrameFloodTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
// Frame structure:
// | Len0 | Len1 | Len2 | Type | Flags | StreamID0 |StreamID1 |StreamID2 |StreamID3 | Payload... |
@@ -72,7 +72,7 @@ public class FrameFloodTest
public void testInvalidHeadersFrameFlood() throws Exception
{
// Invalid MetaData (no method, no scheme, etc).
- MetaData.Request metadata = new MetaData.Request(null, (String)null, null, null, HttpVersion.HTTP_2, null, -1);
+ MetaData.Request metadata = new MetaData.Request(null, null, null, null, HttpVersion.HTTP_2, null, -1);
HpackEncoder encoder = new HpackEncoder();
ByteBuffer buffer = ByteBuffer.allocate(1024);
encoder.encode(buffer, metadata);
@@ -123,7 +123,7 @@ public class FrameFloodTest
private void testFrameFlood(byte[] preamble, byte[] bytes)
{
AtomicBoolean failed = new AtomicBoolean();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java
index df27cdc3417..15d5c4fa5d1 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/GoAwayGenerateParseTest.java
@@ -22,8 +22,8 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.GoAwayGenerator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
@@ -32,15 +32,15 @@ import static org.junit.jupiter.api.Assertions.assertNull;
public class GoAwayGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator());
+ GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onGoAway(GoAwayFrame frame)
@@ -56,11 +56,11 @@ public class GoAwayGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateGoAway(lease, lastStreamId, error, null);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateGoAway(accumulator, lastStreamId, error, null);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -79,10 +79,10 @@ public class GoAwayGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator());
+ GoAwayGenerator generator = new GoAwayGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onGoAway(GoAwayFrame frame)
@@ -100,11 +100,11 @@ public class GoAwayGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateGoAway(lease, lastStreamId, error, payload);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateGoAway(accumulator, lastStreamId, error, payload);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java
index 90f89f05cd0..6e1fe0d61aa 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersGenerateParseTest.java
@@ -28,8 +28,8 @@ import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.HeadersGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -38,12 +38,12 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class HeadersGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder());
+ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
int streamId = 13;
HttpFields fields = HttpFields.build()
@@ -52,7 +52,7 @@ public class HeadersGenerateParseTest
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields, -1);
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -65,12 +65,12 @@ public class HeadersGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
PriorityFrame priorityFrame = new PriorityFrame(streamId, 3 * streamId, 200, true);
- generator.generateHeaders(lease, streamId, metaData, priorityFrame, true);
+ generator.generateHeaders(accumulator, streamId, metaData, priorityFrame, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -102,10 +102,10 @@ public class HeadersGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder());
+ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -124,12 +124,12 @@ public class HeadersGenerateParseTest
.put("User-Agent", "Jetty");
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:8080"), "/path", HttpVersion.HTTP_2, fields, -1);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
PriorityFrame priorityFrame = new PriorityFrame(streamId, 3 * streamId, 200, true);
- generator.generateHeaders(lease, streamId, metaData, priorityFrame, true);
+ generator.generateHeaders(accumulator, streamId, metaData, priorityFrame, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
buffer = buffer.slice();
while (buffer.hasRemaining())
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersTooLargeParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersTooLargeParseTest.java
index 141176f4efd..c049a51f48c 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersTooLargeParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/HeadersTooLargeParseTest.java
@@ -28,8 +28,8 @@ import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.HeadersGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -37,7 +37,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class HeadersTooLargeParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testProtocolErrorURITooLong() throws HpackException
@@ -64,10 +64,10 @@ public class HeadersTooLargeParseTest
private void assertProtocolError(int maxHeaderSize, MetaData.Request metaData) throws HpackException
{
- HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(), new HpackEncoder());
+ HeadersGenerator generator = new HeadersGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
AtomicInteger failure = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
@@ -78,11 +78,11 @@ public class HeadersTooLargeParseTest
parser.init(UnaryOperator.identity());
int streamId = 48;
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
PriorityFrame priorityFrame = new PriorityFrame(streamId, 3 * streamId, 200, true);
- int len = generator.generateHeaders(lease, streamId, metaData, priorityFrame, true);
+ int len = generator.generateHeaders(accumulator, streamId, metaData, priorityFrame, true);
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining() && failure.get() == 0)
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java
index 478a6f8e4f5..126151780fb 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/MaxFrameSizeParseTest.java
@@ -19,15 +19,15 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class MaxFrameSizeParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testMaxFrameSize()
@@ -35,7 +35,7 @@ public class MaxFrameSizeParseTest
int maxFrameLength = Frame.DEFAULT_MAX_LENGTH + 16;
AtomicInteger failure = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java
index 39f1f8c0d3b..99bd496e8ca 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PingGenerateParseTest.java
@@ -22,8 +22,8 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.PingGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.NanoTime;
import org.junit.jupiter.api.Test;
@@ -33,15 +33,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class PingGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- PingGenerator generator = new PingGenerator(new HeaderGenerator());
+ PingGenerator generator = new PingGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPing(PingFrame frame)
@@ -57,11 +57,11 @@ public class PingGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePing(lease, payload, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePing(accumulator, payload, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -79,10 +79,10 @@ public class PingGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- PingGenerator generator = new PingGenerator(new HeaderGenerator());
+ PingGenerator generator = new PingGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPing(PingFrame frame)
@@ -98,11 +98,11 @@ public class PingGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePing(lease, payload, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePing(accumulator, payload, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -120,10 +120,10 @@ public class PingGenerateParseTest
@Test
public void testPayloadAsLong() throws Exception
{
- PingGenerator generator = new PingGenerator(new HeaderGenerator());
+ PingGenerator generator = new PingGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPing(PingFrame frame)
@@ -133,11 +133,11 @@ public class PingGenerateParseTest
}, 4096, 8192);
parser.init(UnaryOperator.identity());
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
PingFrame ping = new PingFrame(NanoTime.now(), true);
- generator.generate(lease, ping);
+ generator.generate(accumulator, ping);
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java
index 8d048fbaa00..27a372243a6 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PriorityGenerateParseTest.java
@@ -21,23 +21,23 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.PriorityGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class PriorityGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator());
+ PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPriority(PriorityFrame frame)
@@ -55,11 +55,11 @@ public class PriorityGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePriority(lease, streamId, parentStreamId, weight, exclusive);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePriority(accumulator, streamId, parentStreamId, weight, exclusive);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -79,10 +79,10 @@ public class PriorityGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator());
+ PriorityGenerator generator = new PriorityGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPriority(PriorityFrame frame)
@@ -100,11 +100,11 @@ public class PriorityGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePriority(lease, streamId, parentStreamId, weight, exclusive);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePriority(accumulator, streamId, parentStreamId, weight, exclusive);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java
index 812d4ff2f89..ce5b61a8610 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/PushPromiseGenerateParseTest.java
@@ -28,8 +28,8 @@ import org.eclipse.jetty.http2.hpack.HpackEncoder;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.PushPromiseGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -37,15 +37,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class PushPromiseGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder());
+ PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPushPromise(PushPromiseFrame frame)
@@ -65,11 +65,11 @@ public class PushPromiseGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePushPromise(lease, streamId, promisedStreamId, metaData);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePushPromise(accumulator, streamId, promisedStreamId, metaData);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -95,10 +95,10 @@ public class PushPromiseGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(), new HpackEncoder());
+ PushPromiseGenerator generator = new PushPromiseGenerator(new HeaderGenerator(bufferPool), new HpackEncoder());
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onPushPromise(PushPromiseFrame frame)
@@ -118,11 +118,11 @@ public class PushPromiseGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generatePushPromise(lease, streamId, promisedStreamId, metaData);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generatePushPromise(accumulator, streamId, promisedStreamId, metaData);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -134,7 +134,7 @@ public class PushPromiseGenerateParseTest
PushPromiseFrame frame = frames.get(0);
assertEquals(streamId, frame.getStreamId());
assertEquals(promisedStreamId, frame.getPromisedStreamId());
- MetaData.Request request = (MetaData.Request)frame.getMetaData();
+ MetaData.Request request = frame.getMetaData();
assertEquals(metaData.getMethod(), request.getMethod());
assertEquals(metaData.getURI(), request.getURI());
for (int j = 0; j < fields.size(); ++j)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java
index 5bbbb44c109..4ed17c70e9d 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/ResetGenerateParseTest.java
@@ -21,23 +21,23 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.ResetGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ResetGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- ResetGenerator generator = new ResetGenerator(new HeaderGenerator());
+ ResetGenerator generator = new ResetGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onReset(ResetFrame frame)
@@ -53,11 +53,11 @@ public class ResetGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateReset(lease, streamId, error);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateReset(accumulator, streamId, error);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -75,10 +75,10 @@ public class ResetGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- ResetGenerator generator = new ResetGenerator(new HeaderGenerator());
+ ResetGenerator generator = new ResetGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onReset(ResetFrame frame)
@@ -94,11 +94,11 @@ public class ResetGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateReset(lease, streamId, error);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateReset(accumulator, streamId, error);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java
index a5689245051..735d074418c 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/SettingsGenerateParseTest.java
@@ -26,8 +26,8 @@ import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.SettingsGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -35,7 +35,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class SettingsGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParseNoSettings()
@@ -69,10 +69,10 @@ public class SettingsGenerateParseTest
private List testGenerateParse(Map settings)
{
- SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator());
+ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator(bufferPool));
List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -85,11 +85,11 @@ public class SettingsGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateSettings(lease, settings, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateSettings(accumulator, settings, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -104,10 +104,10 @@ public class SettingsGenerateParseTest
@Test
public void testGenerateParseInvalidSettings()
{
- SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator());
+ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator(bufferPool));
AtomicInteger errorRef = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
@@ -119,13 +119,13 @@ public class SettingsGenerateParseTest
Map settings1 = new HashMap<>();
settings1.put(13, 17);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateSettings(lease, settings1, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateSettings(accumulator, settings1, true);
// Modify the length of the frame to make it invalid
- ByteBuffer bytes = lease.getByteBuffers().get(0);
+ ByteBuffer bytes = accumulator.getByteBuffers().get(0);
bytes.putShort(1, (short)(bytes.getShort(1) - 1));
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -139,10 +139,10 @@ public class SettingsGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime()
{
- SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator());
+ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator(bufferPool));
List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -160,11 +160,11 @@ public class SettingsGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateSettings(lease, settings1, true);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateSettings(accumulator, settings1, true);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -184,10 +184,10 @@ public class SettingsGenerateParseTest
@Test
public void testGenerateParseTooManyDifferentSettingsInOneFrame()
{
- SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator());
+ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator(bufferPool));
AtomicInteger errorRef = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
@@ -205,10 +205,10 @@ public class SettingsGenerateParseTest
settings.put(i + 10, i);
}
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateSettings(lease, settings, false);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateSettings(accumulator, settings, false);
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -227,7 +227,7 @@ public class SettingsGenerateParseTest
int maxSettingsKeys = pairs / 2;
AtomicInteger errorRef = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter(), 4096, 8192);
parser.setMaxSettingsKeys(maxSettingsKeys);
parser.setMaxFrameLength(Frame.DEFAULT_MAX_LENGTH);
parser.init(listener -> new Parser.Listener.Wrapper(listener)
@@ -265,10 +265,10 @@ public class SettingsGenerateParseTest
@Test
public void testGenerateParseTooManySettingsInMultipleFrames()
{
- SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator());
+ SettingsGenerator generator = new SettingsGenerator(new HeaderGenerator(bufferPool));
AtomicInteger errorRef = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
@@ -283,13 +283,13 @@ public class SettingsGenerateParseTest
Map settings = new HashMap<>();
settings.put(13, 17);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
for (int i = 0; i < maxSettingsKeys + 1; ++i)
{
- generator.generateSettings(lease, settings, false);
+ generator.generateSettings(accumulator, settings, false);
}
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java
index bd55440be64..68336fb08cf 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/UnknownParseTest.java
@@ -21,8 +21,8 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -30,7 +30,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
public class UnknownParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testParse()
@@ -48,7 +48,7 @@ public class UnknownParseTest
public void testInvalidFrameSize()
{
AtomicInteger failure = new AtomicInteger();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter(), 4096, 8192);
parser.init(listener -> new Parser.Listener.Wrapper(listener)
{
@Override
@@ -73,7 +73,7 @@ public class UnknownParseTest
private void testParse(Function fn)
{
AtomicBoolean failure = new AtomicBoolean();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onConnectionFailure(int error, String reason)
diff --git a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java
index f87496558c9..21a165397b9 100644
--- a/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-common/src/test/java/org/eclipse/jetty/http2/frames/WindowUpdateGenerateParseTest.java
@@ -21,23 +21,23 @@ import java.util.function.UnaryOperator;
import org.eclipse.jetty.http2.internal.generator.HeaderGenerator;
import org.eclipse.jetty.http2.internal.generator.WindowUpdateGenerator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class WindowUpdateGenerateParseTest
{
- private final ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
@Test
public void testGenerateParse() throws Exception
{
- WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator());
+ WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onWindowUpdate(WindowUpdateFrame frame)
@@ -53,11 +53,11 @@ public class WindowUpdateGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateWindowUpdate(lease, streamId, windowUpdate);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateWindowUpdate(accumulator, streamId, windowUpdate);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
@@ -75,10 +75,10 @@ public class WindowUpdateGenerateParseTest
@Test
public void testGenerateParseOneByteAtATime() throws Exception
{
- WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator());
+ WindowUpdateGenerator generator = new WindowUpdateGenerator(new HeaderGenerator(bufferPool));
final List frames = new ArrayList<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onWindowUpdate(WindowUpdateFrame frame)
@@ -94,11 +94,11 @@ public class WindowUpdateGenerateParseTest
// Iterate a few times to be sure generator and parser are properly reset.
for (int i = 0; i < 2; ++i)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.generateWindowUpdate(lease, streamId, windowUpdate);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.generateWindowUpdate(accumulator, streamId, windowUpdate);
frames.clear();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
while (buffer.hasRemaining())
{
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
index b49b9cccaed..b85935bc9ee 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java
@@ -271,7 +271,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
{
ServerSessionListener listener = newSessionListener(connector, endPoint);
- Generator generator = new Generator(connector.getByteBufferPool(), isUseOutputDirectByteBuffers(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment());
+ Generator generator = new Generator(connector.getRetainableByteBufferPool(), isUseOutputDirectByteBuffers(), getMaxDynamicTableSize(), getMaxHeaderBlockFragment());
FlowControlStrategy flowControl = getFlowControlStrategyFactory().newFlowControlStrategy();
HTTP2ServerSession session = new HTTP2ServerSession(connector.getScheduler(), endPoint, generator, listener, flowControl);
session.setMaxLocalStreams(getMaxConcurrentStreams());
@@ -291,7 +291,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
parser.setMaxFrameLength(getMaxFrameLength());
parser.setMaxSettingsKeys(getMaxSettingsKeys());
- RetainableByteBufferPool retainableByteBufferPool = connector.getByteBufferPool().asRetainableByteBufferPool();
+ RetainableByteBufferPool retainableByteBufferPool = connector.getRetainableByteBufferPool();
HTTP2Connection connection = new HTTP2ServerConnection(retainableByteBufferPool, connector,
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
@@ -305,7 +305,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
private ServerParser newServerParser(Connector connector, ServerParser.Listener listener, RateControl rateControl)
{
- return new ServerParser(connector.getByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize(), rateControl);
+ return new ServerParser(connector.getRetainableByteBufferPool(), listener, getMaxDynamicTableSize(), getHttpConfiguration().getRequestHeaderSize(), rateControl);
}
@ManagedObject("The container of HTTP/2 sessions")
diff --git a/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java b/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java
index 06d4026956f..2d0162cc4fb 100644
--- a/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java
+++ b/jetty-core/jetty-http2/jetty-http2-server/src/main/java/org/eclipse/jetty/http2/server/internal/HttpStreamOverHTTP2.java
@@ -253,7 +253,7 @@ public class HttpStreamOverHTTP2 implements HttpStream, HTTP2Channel.Server
data.release();
return Content.Chunk.EOF;
}
- return Content.Chunk.asChunk(frame.getData(), frame.isEndStream(), data);
+ return Content.Chunk.asChunk(frame.getByteBuffer(), frame.isEndStream(), data);
}
@Override
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
index aa6fd997ee3..cbf4b859cbb 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/AbstractServerTest.java
@@ -29,8 +29,8 @@ import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
@@ -42,7 +42,7 @@ import org.junit.jupiter.api.AfterEach;
public class AbstractServerTest
{
protected ServerConnector connector;
- protected ByteBufferPool byteBufferPool;
+ protected RetainableByteBufferPool bufferPool;
protected Generator generator;
protected Server server;
protected String path;
@@ -68,8 +68,8 @@ public class AbstractServerTest
connector = new ServerConnector(server, connectionFactory);
server.addConnector(connector);
path = "/test";
- byteBufferPool = new MappedByteBufferPool();
- generator = new Generator(byteBufferPool);
+ bufferPool = new ArrayRetainableByteBufferPool();
+ generator = new Generator(bufferPool);
}
protected MetaData.Request newRequest(String method, HttpFields fields)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BadURITest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BadURITest.java
index 0607b266261..8cf88772aea 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BadURITest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/BadURITest.java
@@ -31,7 +31,7 @@ import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
@@ -97,8 +97,8 @@ public class BadURITest
}
});
- ByteBufferPool byteBufferPool = connector.getByteBufferPool();
- Generator generator = new Generator(byteBufferPool);
+ RetainableByteBufferPool bufferPool = connector.getRetainableByteBufferPool();
+ Generator generator = new Generator(bufferPool);
// Craft a request with a bad URI, it will not hit the Handler.
MetaData.Request metaData1 = new MetaData.Request(
@@ -111,15 +111,15 @@ public class BadURITest
HttpFields.EMPTY,
-1
);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
- generator.control(lease, new HeadersFrame(1, metaData1, null, true));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
+ generator.control(accumulator, new HeadersFrame(1, metaData1, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
@@ -128,7 +128,7 @@ public class BadURITest
Thread.sleep(1000);
// Send a second request and verify that it hits the Handler.
- lease.recycle();
+ accumulator.release();
MetaData.Request metaData2 = new MetaData.Request(
HttpMethod.GET.asString(),
HttpScheme.HTTP.asString(),
@@ -138,8 +138,8 @@ public class BadURITest
HttpFields.EMPTY,
-1
);
- generator.control(lease, new HeadersFrame(3, metaData2, null, true));
- for (ByteBuffer buffer : lease.getByteBuffers())
+ generator.control(accumulator, new HeadersFrame(3, metaData2, null, true));
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
index f82498cf7f0..9ecb271995b 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/CloseTest.java
@@ -37,7 +37,7 @@ import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@@ -74,21 +74,21 @@ public class CloseTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -135,17 +135,17 @@ public class CloseTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
- generator.control(lease, new GoAwayFrame(1, ErrorCode.NO_ERROR.code, "OK".getBytes(StandardCharsets.UTF_8)));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new GoAwayFrame(1, ErrorCode.NO_ERROR.code, "OK".getBytes(StandardCharsets.UTF_8)));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
@@ -153,7 +153,7 @@ public class CloseTest extends AbstractServerTest
// Don't close the connection; the server should close.
final CountDownLatch responseLatch = new CountDownLatch(1);
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -202,23 +202,23 @@ public class CloseTest extends AbstractServerTest
});
connector.setIdleTimeout(idleTimeout);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
final CountDownLatch responseLatch = new CountDownLatch(1);
final CountDownLatch closeLatch = new CountDownLatch(1);
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
index 2d3e98b9526..64da0dda26a 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/DataDemandTest.java
@@ -35,8 +35,8 @@ import org.eclipse.jetty.http2.frames.DataFrame;
import org.eclipse.jetty.http2.frames.HeadersFrame;
import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.generator.Generator;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.Promise;
@@ -119,7 +119,7 @@ public class DataDemandTest extends AbstractTest
await().atMost(1, TimeUnit.SECONDS).until(() -> serverQueue.size() == count.get() + 1);
count.incrementAndGet();
long sum = serverQueue.stream()
- .mapToLong(data -> data.frame().getData().remaining())
+ .mapToLong(data -> data.frame().getByteBuffer().remaining())
.sum();
if (sum == length)
break;
@@ -155,7 +155,7 @@ public class DataDemandTest extends AbstractTest
await().atMost(1, TimeUnit.SECONDS).until(() -> clientQueue.size() == count.get() + 1);
count.incrementAndGet();
long sum = clientQueue.stream()
- .mapToLong(data -> data.frame().getData().remaining())
+ .mapToLong(data -> data.frame().getByteBuffer().remaining())
.sum();
if (sum == length)
break;
@@ -365,17 +365,17 @@ public class DataDemandTest extends AbstractTest
// Generate a lot of small DATA frames and write them in a single
// write so that the server will continuously be notified and demand,
// which will test that it won't throw StackOverflowError.
- MappedByteBufferPool byteBufferPool = new MappedByteBufferPool();
- Generator generator = new Generator(byteBufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ Generator generator = new Generator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
for (int i = 512; i >= 0; --i)
- generator.data(lease, new DataFrame(clientStream.getId(), ByteBuffer.allocate(1), i == 0), 1);
+ generator.data(accumulator, new DataFrame(clientStream.getId(), ByteBuffer.allocate(1), i == 0), 1);
// Since this is a naked write, we need to wait that the
// client finishes writing the SETTINGS reply to the server
// during connection initialization, or we risk a WritePendingException.
Thread.sleep(1000);
- ((HTTP2Session)clientStream.getSession()).getEndPoint().write(Callback.NOOP, lease.getByteBuffers().toArray(new ByteBuffer[0]));
+ ((HTTP2Session)clientStream.getSession()).getEndPoint().write(Callback.NOOP, accumulator.getByteBuffers().toArray(ByteBuffer[]::new));
assertTrue(latch.await(15, TimeUnit.SECONDS));
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
index b23bbb3c850..bc1a11a3a5a 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/FlowControlStrategyTest.java
@@ -51,7 +51,7 @@ import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.HTTP2Stream;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
@@ -667,7 +667,7 @@ public abstract class FlowControlStrategyTest
Stream.Data data = stream.readData();
DataFrame frame = data.frame();
int remaining = frame.remaining();
- frame.getData().get(bytes, received, remaining);
+ frame.getByteBuffer().get(bytes, received, remaining);
this.received += remaining;
data.release();
if (frame.isEndStream())
@@ -737,7 +737,7 @@ public abstract class FlowControlStrategyTest
public void onDataAvailable(Stream stream)
{
Stream.Data data = stream.readData();
- responseContent.put(data.frame().getData());
+ responseContent.put(data.frame().getByteBuffer());
data.release();
if (data.frame().isEndStream())
latch.countDown();
@@ -844,10 +844,10 @@ public abstract class FlowControlStrategyTest
// Now the client is supposed to not send more frames.
// If it does, the connection must be closed.
HTTP2Session http2Session = (HTTP2Session)session;
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(connector.getByteBufferPool());
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
ByteBuffer extraData = ByteBuffer.allocate(1024);
- http2Session.getGenerator().data(lease, new DataFrame(stream.getId(), extraData, true), extraData.remaining());
- List buffers = lease.getByteBuffers();
+ http2Session.getGenerator().data(accumulator, new DataFrame(stream.getId(), extraData, true), extraData.remaining());
+ List buffers = accumulator.getByteBuffers();
http2Session.getEndPoint().write(Callback.NOOP, buffers.toArray(new ByteBuffer[0]));
// Expect the connection to be closed.
@@ -949,10 +949,10 @@ public abstract class FlowControlStrategyTest
// Now the client is supposed to not send more frames.
// If it does, the connection must be closed.
HTTP2Session http2Session = (HTTP2Session)session;
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(connector.getByteBufferPool());
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
ByteBuffer extraData = ByteBuffer.allocate(1024);
- http2Session.getGenerator().data(lease, new DataFrame(stream.getId(), extraData, true), extraData.remaining());
- List buffers = lease.getByteBuffers();
+ http2Session.getGenerator().data(accumulator, new DataFrame(stream.getId(), extraData, true), extraData.remaining());
+ List buffers = accumulator.getByteBuffers();
http2Session.getEndPoint().write(Callback.NOOP, buffers.toArray(new ByteBuffer[0]));
// Expect the connection to be closed.
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
index ae23a8b12e7..c9d7d7d080d 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2CServerTest.java
@@ -38,10 +38,10 @@ import org.eclipse.jetty.http2.frames.PrefaceFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.ServerConnector;
@@ -150,13 +150,13 @@ public class HTTP2CServerTest extends AbstractServerTest
assertTrue(upgrade.toString().startsWith("HTTP/1.1 101 "));
- byteBufferPool = new MappedByteBufferPool();
- generator = new Generator(byteBufferPool);
+ bufferPool = new ArrayRetainableByteBufferPool();
+ generator = new Generator(bufferPool);
final AtomicReference headersRef = new AtomicReference<>();
final AtomicReference dataRef = new AtomicReference<>();
final AtomicReference latchRef = new AtomicReference<>(new CountDownLatch(2));
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
@@ -186,7 +186,7 @@ public class HTTP2CServerTest extends AbstractServerTest
DataFrame responseData = dataRef.get();
assertNotNull(responseData);
- String content = BufferUtil.toString(responseData.getData());
+ String content = BufferUtil.toString(responseData.getByteBuffer());
// The upgrade request is seen as HTTP/1.1.
assertThat(content, containsString("Hello from Jetty using HTTP/2.0"));
@@ -196,12 +196,12 @@ public class HTTP2CServerTest extends AbstractServerTest
headersRef.set(null);
dataRef.set(null);
latchRef.set(new CountDownLatch(2));
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:" + connector.getLocalPort()), "/two", HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
- generator.control(lease, new HeadersFrame(3, metaData, null, true));
- for (ByteBuffer buffer : lease.getByteBuffers())
+ generator.control(accumulator, new HeadersFrame(3, metaData, null, true));
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
@@ -219,7 +219,7 @@ public class HTTP2CServerTest extends AbstractServerTest
responseData = dataRef.get();
assertNotNull(responseData);
- content = BufferUtil.toString(responseData.getData());
+ content = BufferUtil.toString(responseData.getByteBuffer());
assertThat(content, containsString("Hello from Jetty using HTTP/2.0"));
assertThat(content, containsString("uri=/two"));
@@ -231,28 +231,28 @@ public class HTTP2CServerTest extends AbstractServerTest
{
final CountDownLatch latch = new CountDownLatch(3);
- byteBufferPool = new MappedByteBufferPool();
- generator = new Generator(byteBufferPool);
+ bufferPool = new ArrayRetainableByteBufferPool();
+ generator = new Generator(bufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = new MetaData.Request("GET", HttpScheme.HTTP.asString(), new HostPortHttpField("localhost:" + connector.getLocalPort()), "/test", HttpVersion.HTTP_2, HttpFields.EMPTY, -1);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
client.setSoTimeout(5000);
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
final AtomicReference headersRef = new AtomicReference<>();
final AtomicReference dataRef = new AtomicReference<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -288,7 +288,7 @@ public class HTTP2CServerTest extends AbstractServerTest
DataFrame responseData = dataRef.get();
assertNotNull(responseData);
- String s = BufferUtil.toString(responseData.getData());
+ String s = BufferUtil.toString(responseData.getByteBuffer());
assertThat(s, containsString("Hello from Jetty using HTTP/2.0"));
assertThat(s, containsString("uri=/test"));
@@ -328,18 +328,18 @@ public class HTTP2CServerTest extends AbstractServerTest
// Now send an HTTP/2 direct request, which
// will have the PRI * HTTP/2.0 preface.
- byteBufferPool = new MappedByteBufferPool();
- generator = new Generator(byteBufferPool);
+ bufferPool = new ArrayRetainableByteBufferPool();
+ generator = new Generator(bufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
client.setSoTimeout(5000);
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
index 106d8f7d3dd..9b1a83bbfd7 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2ServerTest.java
@@ -47,8 +47,9 @@ import org.eclipse.jetty.http2.internal.Flags;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.ManagedSelector;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.SocketChannelEndPoint;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.Handler;
@@ -84,19 +85,19 @@ public class HTTP2ServerTest extends AbstractServerTest
// No preface bytes.
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- final CountDownLatch latch = new CountDownLatch(1);
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ CountDownLatch latch = new CountDownLatch(1);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onGoAway(GoAwayFrame frame)
@@ -115,7 +116,7 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testRequestResponseNoContent() throws Exception
{
- final CountDownLatch latch = new CountDownLatch(3);
+ CountDownLatch latch = new CountDownLatch(3);
startServer(new Handler.Abstract()
{
@Override
@@ -127,22 +128,22 @@ public class HTTP2ServerTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- final AtomicReference frameRef = new AtomicReference<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ AtomicReference frameRef = new AtomicReference<>();
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -173,8 +174,8 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testRequestResponseContent() throws Exception
{
- final byte[] content = "Hello, world!".getBytes(StandardCharsets.UTF_8);
- final CountDownLatch latch = new CountDownLatch(4);
+ byte[] content = "Hello, world!".getBytes(StandardCharsets.UTF_8);
+ CountDownLatch latch = new CountDownLatch(4);
startServer(new Handler.Abstract()
{
@Override
@@ -186,23 +187,23 @@ public class HTTP2ServerTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- final AtomicReference headersRef = new AtomicReference<>();
- final AtomicReference dataRef = new AtomicReference<>();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ AtomicReference headersRef = new AtomicReference<>();
+ AtomicReference dataRef = new AtomicReference<>();
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -237,7 +238,7 @@ public class HTTP2ServerTest extends AbstractServerTest
DataFrame responseData = dataRef.get();
assertNotNull(responseData);
- assertArrayEquals(content, BufferUtil.toArray(responseData.getData()));
+ assertArrayEquals(content, BufferUtil.toArray(responseData.getByteBuffer()));
}
}
@@ -254,23 +255,23 @@ public class HTTP2ServerTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
- generator.control(lease, new PingFrame(new byte[8], false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
+ generator.control(accumulator, new PingFrame(new byte[8], false));
// Modify the length of the frame to a wrong one.
- lease.getByteBuffers().get(2).putShort(0, (short)7);
+ accumulator.getByteBuffers().get(2).putShort(0, (short)7);
- final CountDownLatch latch = new CountDownLatch(1);
+ CountDownLatch latch = new CountDownLatch(1);
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onGoAway(GoAwayFrame frame)
@@ -300,23 +301,23 @@ public class HTTP2ServerTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
- generator.control(lease, new PingFrame(new byte[8], false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
+ generator.control(accumulator, new PingFrame(new byte[8], false));
// Modify the streamId of the frame to non zero.
- lease.getByteBuffers().get(2).putInt(4, 1);
+ accumulator.getByteBuffers().get(2).putInt(4, 1);
- final CountDownLatch latch = new CountDownLatch(1);
+ CountDownLatch latch = new CountDownLatch(1);
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onGoAway(GoAwayFrame frame)
@@ -336,8 +337,8 @@ public class HTTP2ServerTest extends AbstractServerTest
@Test
public void testCommitFailure() throws Exception
{
- final long delay = 1000;
- final AtomicBoolean broken = new AtomicBoolean();
+ long delay = 1000;
+ AtomicBoolean broken = new AtomicBoolean();
startServer(new Handler.Abstract()
{
@Override
@@ -373,22 +374,22 @@ public class HTTP2ServerTest extends AbstractServerTest
server.addConnector(connector2);
server.start();
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector2.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
// The server will close the connection abruptly since it
// cannot write and therefore cannot even send the GO_AWAY.
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter(), 4096, 8192);
parser.init(UnaryOperator.identity());
boolean closed = parseResponse(client, parser, 2 * delay);
assertTrue(closed);
@@ -413,22 +414,22 @@ public class HTTP2ServerTest extends AbstractServerTest
}
});
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
output.flush();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter(), 4096, 8192);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter(), 4096, 8192);
parser.init(UnaryOperator.identity());
boolean closed = parseResponse(client, parser);
@@ -442,12 +443,12 @@ public class HTTP2ServerTest extends AbstractServerTest
{
testRequestWithContinuationFrames(null, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
- return lease;
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
+ return accumulator;
});
}
@@ -457,12 +458,12 @@ public class HTTP2ServerTest extends AbstractServerTest
PriorityFrame priority = new PriorityFrame(1, 13, 200, true);
testRequestWithContinuationFrames(priority, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, priority, true));
- return lease;
+ generator.control(accumulator, new HeadersFrame(1, metaData, priority, true));
+ return accumulator;
});
}
@@ -471,19 +472,19 @@ public class HTTP2ServerTest extends AbstractServerTest
{
testRequestWithContinuationFrames(null, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
// Take the HeadersFrame header and set the length to zero.
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
ByteBuffer headersFrameHeader = buffers.get(2);
headersFrameHeader.put(0, (byte)0);
headersFrameHeader.putShort(1, (short)0);
// Insert a CONTINUATION frame header for the body of the HEADERS frame.
- lease.insert(3, buffers.get(4).slice(), false);
- return lease;
+ accumulator.insert(3, RetainableByteBuffer.wrap(buffers.get(4).slice()));
+ return accumulator;
});
}
@@ -493,19 +494,19 @@ public class HTTP2ServerTest extends AbstractServerTest
PriorityFrame priority = new PriorityFrame(1, 13, 200, true);
testRequestWithContinuationFrames(null, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, priority, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, priority, true));
// Take the HeadersFrame header and set the length to just the priority frame.
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
ByteBuffer headersFrameHeader = buffers.get(2);
headersFrameHeader.put(0, (byte)0);
headersFrameHeader.putShort(1, (short)PriorityFrame.PRIORITY_LENGTH);
// Insert a CONTINUATION frame header for the body of the HEADERS frame.
- lease.insert(3, buffers.get(4).slice(), false);
- return lease;
+ accumulator.insert(3, RetainableByteBuffer.wrap(buffers.get(4).slice()));
+ return accumulator;
});
}
@@ -514,13 +515,13 @@ public class HTTP2ServerTest extends AbstractServerTest
{
testRequestWithContinuationFrames(null, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
// Take the ContinuationFrame header, duplicate it, and set the length to zero.
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
ByteBuffer continuationFrameHeader = buffers.get(4);
ByteBuffer duplicate = ByteBuffer.allocate(continuationFrameHeader.remaining());
duplicate.put(continuationFrameHeader).flip();
@@ -528,8 +529,8 @@ public class HTTP2ServerTest extends AbstractServerTest
continuationFrameHeader.put(0, (byte)0);
continuationFrameHeader.putShort(1, (short)0);
// Insert a CONTINUATION frame header for the body of the previous CONTINUATION frame.
- lease.insert(5, duplicate, false);
- return lease;
+ accumulator.insert(5, RetainableByteBuffer.wrap(duplicate));
+ return accumulator;
});
}
@@ -538,13 +539,13 @@ public class HTTP2ServerTest extends AbstractServerTest
{
testRequestWithContinuationFrames(null, () ->
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
MetaData.Request metaData = newRequest("GET", HttpFields.EMPTY);
- generator.control(lease, new HeadersFrame(1, metaData, null, true));
+ generator.control(accumulator, new HeadersFrame(1, metaData, null, true));
// Take the last CONTINUATION frame and reset the flag.
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
ByteBuffer continuationFrameHeader = buffers.get(buffers.size() - 2);
continuationFrameHeader.put(4, (byte)0);
// Add a last, empty, CONTINUATION frame.
@@ -554,14 +555,14 @@ public class HTTP2ServerTest extends AbstractServerTest
(byte)Flags.END_HEADERS,
0, 0, 0, 1 // Stream ID
});
- lease.append(last, false);
- return lease;
+ accumulator.append(RetainableByteBuffer.wrap(last));
+ return accumulator;
});
}
- private void testRequestWithContinuationFrames(PriorityFrame priorityFrame, Callable frames) throws Exception
+ private void testRequestWithContinuationFrames(PriorityFrame priorityFrame, Callable frames) throws Exception
{
- final CountDownLatch serverLatch = new CountDownLatch(1);
+ CountDownLatch serverLatch = new CountDownLatch(1);
startServer(new ServerSessionListener()
{
@Override
@@ -585,14 +586,14 @@ public class HTTP2ServerTest extends AbstractServerTest
return null;
}
});
- generator = new Generator(byteBufferPool, 4096, 4);
+ generator = new Generator(bufferPool, 4096, 4);
- ByteBufferPool.Lease lease = frames.call();
+ RetainableByteBufferPool.Accumulator accumulator = frames.call();
try (Socket client = new Socket("localhost", connector.getLocalPort()))
{
OutputStream output = client.getOutputStream();
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
@@ -600,8 +601,8 @@ public class HTTP2ServerTest extends AbstractServerTest
assertTrue(serverLatch.await(5, TimeUnit.SECONDS));
- final CountDownLatch clientLatch = new CountDownLatch(1);
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ CountDownLatch clientLatch = new CountDownLatch(1);
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onHeaders(HeadersFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
index 39aa89c05f2..ff84ba9863a 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HTTP2Test.java
@@ -201,7 +201,7 @@ public class HTTP2Test extends AbstractTest
Stream.Data data = stream.readData();
DataFrame frame = data.frame();
assertTrue(frame.isEndStream());
- assertEquals(ByteBuffer.wrap(content), frame.getData());
+ assertEquals(ByteBuffer.wrap(content), frame.getByteBuffer());
data.release();
latch.countDown();
}
@@ -593,10 +593,10 @@ public class HTTP2Test extends AbstractTest
DataFrame data1 = new DataFrame(stream.getId(), ByteBuffer.allocate(1024), false)
{
@Override
- public ByteBuffer getData()
+ public ByteBuffer getByteBuffer()
{
sleep(2 * sleep);
- return super.getData();
+ return super.getByteBuffer();
}
};
DataFrame data2 = new DataFrame(stream.getId(), BufferUtil.EMPTY_BUFFER, true);
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
index 20ab9759301..915673de3af 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/HttpClientTransportOverHTTP2Test.java
@@ -67,10 +67,10 @@ import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.ServerParser;
import org.eclipse.jetty.http2.server.RawHTTP2ServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.ClientConnector;
import org.eclipse.jetty.io.Content;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.Request;
@@ -111,7 +111,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
assertTrue(http2Client.isStarted());
assertSame(httpClient.getExecutor(), http2Client.getExecutor());
assertSame(httpClient.getScheduler(), http2Client.getScheduler());
- assertSame(httpClient.getByteBufferPool(), http2Client.getByteBufferPool());
+ assertSame(httpClient.getRetainableByteBufferPool(), http2Client.getRetainableByteBufferPool());
assertEquals(httpClient.getConnectTimeout(), http2Client.getConnectTimeout());
assertEquals(httpClient.getIdleTimeout(), http2Client.getIdleTimeout());
assertEquals(httpClient.isUseInputDirectByteBuffers(), http2Client.isUseInputDirectByteBuffers());
@@ -541,9 +541,9 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
resultLatch.countDown();
});
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- Generator generator = new Generator(byteBufferPool);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ Generator generator = new Generator(bufferPool);
try (Socket socket = server.accept())
{
@@ -551,7 +551,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
OutputStream output = socket.getOutputStream();
InputStream input = socket.getInputStream();
- ServerParser parser = new ServerParser(byteBufferPool, new ServerParser.Listener.Adapter()
+ ServerParser parser = new ServerParser(bufferPool, new ServerParser.Listener.Adapter()
{
@Override
public void onPreface()
@@ -559,9 +559,9 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
try
{
// Server's preface.
- generator.control(lease, new SettingsFrame(new HashMap<>(), false));
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), false));
// Reply to client's SETTINGS.
- generator.control(lease, new SettingsFrame(new HashMap<>(), true));
+ generator.control(accumulator, new SettingsFrame(new HashMap<>(), true));
writeFrames();
}
catch (HpackException x)
@@ -578,7 +578,7 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
// Response.
MetaData.Response metaData = new MetaData.Response(HttpVersion.HTTP_2, HttpStatus.OK_200, HttpFields.EMPTY);
HeadersFrame response = new HeadersFrame(request.getStreamId(), metaData, null, true);
- generator.control(lease, response);
+ generator.control(accumulator, response);
writeFrames();
}
catch (HpackException x)
@@ -592,11 +592,11 @@ public class HttpClientTransportOverHTTP2Test extends AbstractTest
try
{
// Write the frames.
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
output.write(BufferUtil.toArray(buffer));
}
- lease.recycle();
+ accumulator.release();
}
catch (Throwable x)
{
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
index 37e040aad78..bab2e80b58c 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/InterleavingTest.java
@@ -158,7 +158,7 @@ public class InterleavingTest extends AbstractTest
if (dataFrame.isEndStream())
++finished;
- BufferUtil.writeTo(dataFrame.getData(), contents.get(streamId));
+ BufferUtil.writeTo(dataFrame.getByteBuffer(), contents.get(streamId));
data.release();
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
index 306b634d46b..dd57d7b906b 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/PrefaceTest.java
@@ -50,9 +50,9 @@ import org.eclipse.jetty.http2.internal.ErrorCode;
import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.internal.parser.Parser;
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
@@ -148,26 +148,26 @@ public class PrefaceTest extends AbstractTest
}
});
- ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = http2Client.getRetainableByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
- Generator generator = new Generator(byteBufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
+ Generator generator = new Generator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
Map clientSettings = new HashMap<>();
clientSettings.put(SettingsFrame.ENABLE_PUSH, 0);
- generator.control(lease, new SettingsFrame(clientSettings, false));
+ generator.control(accumulator, new SettingsFrame(clientSettings, false));
// The PING frame just to make sure the client stops reading.
- generator.control(lease, new PingFrame(true));
+ generator.control(accumulator, new PingFrame(true));
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
Queue settings = new ArrayDeque<>();
AtomicBoolean closed = new AtomicBoolean();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
@@ -183,7 +183,7 @@ public class PrefaceTest extends AbstractTest
}, 4096, 8192);
parser.init(UnaryOperator.identity());
- ByteBuffer buffer = byteBufferPool.acquire(1024, true);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
while (true)
{
BufferUtil.clearToFill(buffer);
@@ -247,7 +247,7 @@ public class PrefaceTest extends AbstractTest
});
server.start();
- ByteBufferPool byteBufferPool = new MappedByteBufferPool();
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
socket.connect(new InetSocketAddress("localhost", connector.getLocalPort()));
@@ -268,7 +268,7 @@ public class PrefaceTest extends AbstractTest
assertTrue(serverSettingsLatch.get().await(5, TimeUnit.SECONDS));
// The 101 response is the reply to the client preface SETTINGS frame.
- ByteBuffer buffer = byteBufferPool.acquire(1024, true);
+ ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
http1:
while (true)
{
@@ -295,13 +295,13 @@ public class PrefaceTest extends AbstractTest
serverSettingsLatch.set(new CountDownLatch(1));
// After the 101, the client must send the connection preface.
- Generator generator = new Generator(byteBufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
+ Generator generator = new Generator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
Map clientSettings = new HashMap<>();
clientSettings.put(SettingsFrame.ENABLE_PUSH, 1);
- generator.control(lease, new SettingsFrame(clientSettings, false));
- List buffers = lease.getByteBuffers();
+ generator.control(accumulator, new SettingsFrame(clientSettings, false));
+ List buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
// However, we should not call onPreface() again.
@@ -311,7 +311,7 @@ public class PrefaceTest extends AbstractTest
CountDownLatch clientSettingsLatch = new CountDownLatch(1);
AtomicBoolean responded = new AtomicBoolean();
- Parser parser = new Parser(byteBufferPool, new Parser.Listener.Adapter()
+ Parser parser = new Parser(bufferPool, new Parser.Listener.Adapter()
{
@Override
public void onSettings(SettingsFrame frame)
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
index c95b1414ba3..01a0d675ec9 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/RawHTTP2ProxyTest.java
@@ -223,7 +223,7 @@ public class RawHTTP2ProxyTest
DataFrame frame = data.frame();
if (LOGGER.isDebugEnabled())
LOGGER.debug("CLIENT received {}", frame);
- assertEquals(buffer1.slice(), frame.getData());
+ assertEquals(buffer1.slice(), frame.getByteBuffer());
data.release();
latch1.countDown();
if (!data.frame().isEndStream())
@@ -461,7 +461,7 @@ public class RawHTTP2ProxyTest
case DATA ->
{
DataFrame clientToProxyFrame = (DataFrame)frameInfo.frame;
- DataFrame proxyToServerFrame = new DataFrame(proxyToServerStream.getId(), clientToProxyFrame.getData(), clientToProxyFrame.isEndStream());
+ DataFrame proxyToServerFrame = new DataFrame(proxyToServerStream.getId(), clientToProxyFrame.getByteBuffer(), clientToProxyFrame.isEndStream());
proxyToServerStream.data(proxyToServerFrame, this);
yield Action.SCHEDULED;
}
@@ -609,7 +609,7 @@ public class RawHTTP2ProxyTest
case DATA ->
{
DataFrame clientToProxyFrame = (DataFrame)frameInfo.frame;
- DataFrame proxyToServerFrame = new DataFrame(serverToProxyStream.getId(), clientToProxyFrame.getData(), clientToProxyFrame.isEndStream());
+ DataFrame proxyToServerFrame = new DataFrame(serverToProxyStream.getId(), clientToProxyFrame.getByteBuffer(), clientToProxyFrame.isEndStream());
proxyToClientStream.data(proxyToServerFrame, this);
yield Action.SCHEDULED;
}
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
index 82e5220abf2..cad58d6b2bd 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamCountTest.java
@@ -33,7 +33,7 @@ import org.eclipse.jetty.http2.frames.ResetFrame;
import org.eclipse.jetty.http2.frames.SettingsFrame;
import org.eclipse.jetty.http2.internal.HTTP2Session;
import org.eclipse.jetty.http2.internal.generator.Generator;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.FuturePromise;
@@ -201,10 +201,10 @@ public class StreamCountTest extends AbstractTest
HeadersFrame frame3 = new HeadersFrame(streamId3, metaData, null, false);
DataFrame data3 = new DataFrame(streamId3, BufferUtil.EMPTY_BUFFER, true);
Generator generator = ((HTTP2Session)session).getGenerator();
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(generator.getByteBufferPool());
- generator.control(lease, frame3);
- generator.data(lease, data3, data3.remaining());
- ((HTTP2Session)session).getEndPoint().write(Callback.NOOP, lease.getByteBuffers().toArray(new ByteBuffer[0]));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, frame3);
+ generator.data(accumulator, data3, data3.remaining());
+ ((HTTP2Session)session).getEndPoint().write(Callback.NOOP, accumulator.getByteBuffers().toArray(ByteBuffer[]::new));
// Expect 2 RST_STREAM frames.
assertTrue(sessionResetLatch.await(5, TimeUnit.SECONDS));
diff --git a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
index 38b22b006ef..1eee6657b24 100644
--- a/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
+++ b/jetty-core/jetty-http2/jetty-http2-tests/src/test/java/org/eclipse/jetty/http2/tests/StreamResetTest.java
@@ -64,8 +64,8 @@ import org.eclipse.jetty.http2.internal.generator.Generator;
import org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
import org.eclipse.jetty.io.AbstractEndPoint;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Content;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.io.WriteFlusher;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.Handler;
@@ -671,7 +671,7 @@ public class StreamResetTest extends AbstractTest
Stream.Data data = stream.readData();
dataQueue.offer(data);
// Do not consume the data yet.
- if (received.addAndGet(data.frame().getData().remaining()) == windowSize)
+ if (received.addAndGet(data.frame().getByteBuffer().remaining()) == windowSize)
latch.countDown();
else
stream.demand();
@@ -724,7 +724,7 @@ public class StreamResetTest extends AbstractTest
Stream.Data data = stream.readData();
dataList.add(data);
// Do not release to stall the flow control window.
- if (received.addAndGet(data.frame().getData().remaining()) == windowSize)
+ if (received.addAndGet(data.frame().getByteBuffer().remaining()) == windowSize)
latch.countDown();
else
stream.demand();
@@ -784,7 +784,7 @@ public class StreamResetTest extends AbstractTest
Stream.Data data = stream.readData();
dataQueue.offer(data);
// Do not consume the data yet.
- if (received.addAndGet(data.frame().getData().remaining()) == windowSize)
+ if (received.addAndGet(data.frame().getByteBuffer().remaining()) == windowSize)
latch.countDown();
else
stream.demand();
@@ -887,30 +887,30 @@ public class StreamResetTest extends AbstractTest
}
});
- ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = http2Client.getRetainableByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
String host = "localhost";
int port = connector.getLocalPort();
socket.connect(new InetSocketAddress(host, port));
- Generator generator = new Generator(byteBufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
+ Generator generator = new Generator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
Map clientSettings = new HashMap<>();
// Max stream HTTP/2 flow control window.
clientSettings.put(SettingsFrame.INITIAL_WINDOW_SIZE, Integer.MAX_VALUE);
- generator.control(lease, new SettingsFrame(clientSettings, false));
+ generator.control(accumulator, new SettingsFrame(clientSettings, false));
// Max session HTTP/2 flow control window.
- generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
+ generator.control(accumulator, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
HttpURI uri = HttpURI.from("http", host, port, "/");
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
int streamId = 3;
HeadersFrame headersFrame = new HeadersFrame(streamId, request, null, true);
- generator.control(lease, headersFrame);
+ generator.control(accumulator, headersFrame);
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
// Wait until the server is TCP congested.
@@ -918,9 +918,9 @@ public class StreamResetTest extends AbstractTest
WriteFlusher flusher = flusherRef.get();
waitUntilTCPCongested(flusher);
- lease.recycle();
- generator.control(lease, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code));
- buffers = lease.getByteBuffers();
+ accumulator.release();
+ generator.control(accumulator, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code));
+ buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
assertTrue(writeLatch1.await(5, TimeUnit.SECONDS));
@@ -978,29 +978,29 @@ public class StreamResetTest extends AbstractTest
}
});
- ByteBufferPool byteBufferPool = http2Client.getByteBufferPool();
+ RetainableByteBufferPool bufferPool = http2Client.getRetainableByteBufferPool();
try (SocketChannel socket = SocketChannel.open())
{
String host = "localhost";
int port = connector.getLocalPort();
socket.connect(new InetSocketAddress(host, port));
- Generator generator = new Generator(byteBufferPool);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(byteBufferPool);
- generator.control(lease, new PrefaceFrame());
+ Generator generator = new Generator(bufferPool);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ generator.control(accumulator, new PrefaceFrame());
Map clientSettings = new HashMap<>();
// Max stream HTTP/2 flow control window.
clientSettings.put(SettingsFrame.INITIAL_WINDOW_SIZE, Integer.MAX_VALUE);
- generator.control(lease, new SettingsFrame(clientSettings, false));
+ generator.control(accumulator, new SettingsFrame(clientSettings, false));
// Max session HTTP/2 flow control window.
- generator.control(lease, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
+ generator.control(accumulator, new WindowUpdateFrame(0, Integer.MAX_VALUE - FlowControlStrategy.DEFAULT_WINDOW_SIZE));
HttpURI uri = HttpURI.from("http", host, port, "/1");
MetaData.Request request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
HeadersFrame headersFrame = new HeadersFrame(3, request, null, true);
- generator.control(lease, headersFrame);
+ generator.control(accumulator, headersFrame);
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
waitUntilTCPCongested(exchanger.exchange(null));
@@ -1010,15 +1010,15 @@ public class StreamResetTest extends AbstractTest
request = new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_2, HttpFields.EMPTY);
int streamId = 5;
headersFrame = new HeadersFrame(streamId, request, null, true);
- generator.control(lease, headersFrame);
- buffers = lease.getByteBuffers();
+ generator.control(accumulator, headersFrame);
+ buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
assertTrue(requestLatch1.await(5, TimeUnit.SECONDS));
// Now reset the second request, which has not started writing yet.
- lease.recycle();
- generator.control(lease, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code));
- buffers = lease.getByteBuffers();
+ accumulator.release();
+ generator.control(accumulator, new ResetFrame(streamId, ErrorCode.CANCEL_STREAM_ERROR.code));
+ buffers = accumulator.getByteBuffers();
socket.write(buffers.toArray(new ByteBuffer[0]));
// Wait to be sure that the server processed the reset.
Thread.sleep(1000);
diff --git a/jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/HttpClientTransportOverHTTP3.java b/jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/HttpClientTransportOverHTTP3.java
index ccf4346e4ab..54487f5c073 100644
--- a/jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/HttpClientTransportOverHTTP3.java
+++ b/jetty-core/jetty-http3/jetty-http3-client-transport/src/main/java/org/eclipse/jetty/http3/client/transport/HttpClientTransportOverHTTP3.java
@@ -69,7 +69,7 @@ public class HttpClientTransportOverHTTP3 extends AbstractHttpClientTransport im
ClientConnector clientConnector = this.client.getClientConnector();
clientConnector.setExecutor(httpClient.getExecutor());
clientConnector.setScheduler(httpClient.getScheduler());
- clientConnector.setByteBufferPool(httpClient.getByteBufferPool());
+ clientConnector.setRetainableByteBufferPool(httpClient.getRetainableByteBufferPool());
clientConnector.setConnectTimeout(Duration.ofMillis(httpClient.getConnectTimeout()));
clientConnector.setConnectBlocking(httpClient.isConnectBlocking());
clientConnector.setBindAddress(httpClient.getBindAddress());
diff --git a/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3Session.java b/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3Session.java
index 5fd2d2a5889..07c003cbe8b 100644
--- a/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3Session.java
+++ b/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3Session.java
@@ -30,6 +30,7 @@ import org.eclipse.jetty.http3.internal.MessageFlusher;
import org.eclipse.jetty.http3.internal.UnidirectionalStreamConnection;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.client.ClientProtocolSession;
import org.eclipse.jetty.quic.client.ClientQuicSession;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
@@ -63,7 +64,8 @@ public class ClientHTTP3Session extends ClientProtocolSession
long encoderStreamId = getQuicSession().newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
QuicStreamEndPoint encoderEndPoint = openInstructionEndPoint(encoderStreamId);
InstructionFlusher encoderInstructionFlusher = new InstructionFlusher(quicSession, encoderEndPoint, EncoderStreamConnection.STREAM_TYPE);
- this.encoder = new QpackEncoder(new InstructionHandler(encoderInstructionFlusher), configuration.getMaxBlockedStreams());
+ RetainableByteBufferPool bufferPool = quicSession.getRetainableByteBufferPool();
+ this.encoder = new QpackEncoder(bufferPool, new InstructionHandler(encoderInstructionFlusher), configuration.getMaxBlockedStreams());
addBean(encoder);
if (LOG.isDebugEnabled())
LOG.debug("created encoder stream #{} on {}", encoderStreamId, encoderEndPoint);
@@ -71,7 +73,7 @@ public class ClientHTTP3Session extends ClientProtocolSession
long decoderStreamId = getQuicSession().newStreamId(StreamType.CLIENT_UNIDIRECTIONAL);
QuicStreamEndPoint decoderEndPoint = openInstructionEndPoint(decoderStreamId);
InstructionFlusher decoderInstructionFlusher = new InstructionFlusher(quicSession, decoderEndPoint, DecoderStreamConnection.STREAM_TYPE);
- this.decoder = new QpackDecoder(new InstructionHandler(decoderInstructionFlusher), configuration.getMaxResponseHeadersSize());
+ this.decoder = new QpackDecoder(bufferPool, new InstructionHandler(decoderInstructionFlusher), configuration.getMaxResponseHeadersSize());
addBean(decoder);
if (LOG.isDebugEnabled())
LOG.debug("created decoder stream #{} on {}", decoderStreamId, decoderEndPoint);
@@ -83,7 +85,7 @@ public class ClientHTTP3Session extends ClientProtocolSession
if (LOG.isDebugEnabled())
LOG.debug("created control stream #{} on {}", controlStreamId, controlEndPoint);
- this.messageFlusher = new MessageFlusher(quicSession.getByteBufferPool(), encoder, configuration.getMaxRequestHeadersSize(), configuration.isUseOutputDirectByteBuffers());
+ this.messageFlusher = new MessageFlusher(quicSession.getRetainableByteBufferPool(), encoder, configuration.getMaxRequestHeadersSize(), configuration.isUseOutputDirectByteBuffers());
addBean(messageFlusher);
}
@@ -197,7 +199,7 @@ public class ClientHTTP3Session extends ClientProtocolSession
private void openUnidirectionalStreamEndPoint(QuicStreamEndPoint endPoint)
{
- UnidirectionalStreamConnection connection = new UnidirectionalStreamConnection(endPoint, getQuicSession().getExecutor(), getQuicSession().getByteBufferPool(), encoder, decoder, session);
+ UnidirectionalStreamConnection connection = new UnidirectionalStreamConnection(endPoint, getQuicSession().getExecutor(), getQuicSession().getRetainableByteBufferPool(), encoder, decoder, session);
endPoint.setConnection(connection);
endPoint.opened();
}
diff --git a/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3StreamConnection.java
index b225dd79ff4..15cdbf20033 100644
--- a/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3StreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-client/src/main/java/org/eclipse/jetty/http3/client/internal/ClientHTTP3StreamConnection.java
@@ -21,6 +21,6 @@ public class ClientHTTP3StreamConnection extends HTTP3StreamConnection
{
public ClientHTTP3StreamConnection(QuicStreamEndPoint endPoint, ClientHTTP3Session session, MessageParser parser)
{
- super(endPoint, session.getQuicSession().getExecutor(), session.getQuicSession().getByteBufferPool(), parser);
+ super(endPoint, session.getQuicSession().getExecutor(), session.getQuicSession().getRetainableByteBufferPool(), parser);
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlFlusher.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlFlusher.java
index f75ab50316f..15e36b7fe97 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlFlusher.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlFlusher.java
@@ -21,7 +21,8 @@ import java.util.Queue;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.internal.generator.ControlGenerator;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicSession;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
import org.eclipse.jetty.util.Callback;
@@ -37,9 +38,9 @@ public class ControlFlusher extends IteratingCallback
private final AutoLock lock = new AutoLock();
private final Queue queue = new ArrayDeque<>();
- private final ByteBufferPool.Lease lease;
- private final ControlGenerator generator;
private final QuicStreamEndPoint endPoint;
+ private final ControlGenerator generator;
+ private final RetainableByteBufferPool.Accumulator accumulator;
private boolean initialized;
private Throwable terminated;
private List entries;
@@ -47,15 +48,16 @@ public class ControlFlusher extends IteratingCallback
public ControlFlusher(QuicSession session, QuicStreamEndPoint endPoint, boolean useDirectByteBuffers)
{
- this.lease = new ByteBufferPool.Lease(session.getByteBufferPool());
this.endPoint = endPoint;
- this.generator = new ControlGenerator(useDirectByteBuffers);
+ RetainableByteBufferPool bufferPool = session.getRetainableByteBufferPool();
+ this.generator = new ControlGenerator(bufferPool, useDirectByteBuffers);
+ this.accumulator = new RetainableByteBufferPool.Accumulator();
}
public boolean offer(Frame frame, Callback callback)
{
Throwable closed;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
closed = terminated;
if (closed == null)
@@ -70,7 +72,7 @@ public class ControlFlusher extends IteratingCallback
@Override
protected Action process()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (queue.isEmpty())
return Action.IDLE;
@@ -83,7 +85,7 @@ public class ControlFlusher extends IteratingCallback
for (Entry entry : entries)
{
- generator.generate(lease, endPoint.getStreamId(), entry.frame, null);
+ generator.generate(accumulator, endPoint.getStreamId(), entry.frame, null);
invocationType = Invocable.combine(invocationType, entry.callback.getInvocationType());
}
@@ -93,12 +95,12 @@ public class ControlFlusher extends IteratingCallback
ByteBuffer buffer = ByteBuffer.allocate(VarLenInt.length(ControlStreamConnection.STREAM_TYPE));
VarLenInt.encode(buffer, ControlStreamConnection.STREAM_TYPE);
buffer.flip();
- lease.insert(0, buffer, false);
+ accumulator.insert(0, RetainableByteBuffer.wrap(buffer));
}
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
if (LOG.isDebugEnabled())
- LOG.debug("writing {} buffers ({} bytes) on {}", buffers.size(), lease.getTotalLength(), this);
+ LOG.debug("writing {} buffers ({} bytes) on {}", buffers.size(), accumulator.getTotalLength(), this);
endPoint.write(this, buffers.toArray(ByteBuffer[]::new));
return Action.SCHEDULED;
}
@@ -109,7 +111,7 @@ public class ControlFlusher extends IteratingCallback
if (LOG.isDebugEnabled())
LOG.debug("succeeded to write {} on {}", entries, this);
- lease.recycle();
+ accumulator.release();
entries.forEach(e -> e.callback.succeeded());
entries.clear();
@@ -125,11 +127,11 @@ public class ControlFlusher extends IteratingCallback
if (LOG.isDebugEnabled())
LOG.debug("failed to write {} on {}", entries, this, failure);
- lease.recycle();
+ accumulator.release();
List allEntries = new ArrayList<>(entries);
entries.clear();
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
terminated = failure;
allEntries.addAll(queue);
@@ -157,21 +159,7 @@ public class ControlFlusher extends IteratingCallback
return String.format("%s#%s", super.toString(), endPoint.getStreamId());
}
- private static class Entry
+ private record Entry(Frame frame, Callback callback)
{
- private final Frame frame;
- private final Callback callback;
-
- private Entry(Frame frame, Callback callback)
- {
- this.frame = frame;
- this.callback = callback;
- }
-
- @Override
- public String toString()
- {
- return frame.toString();
- }
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlStreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlStreamConnection.java
index 0003d604b77..7e0aa7baab8 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlStreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/ControlStreamConnection.java
@@ -18,9 +18,10 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.http3.internal.parser.ControlParser;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -31,15 +32,15 @@ public class ControlStreamConnection extends AbstractConnection implements Conne
public static final long STREAM_TYPE = 0x00;
private static final Logger LOG = LoggerFactory.getLogger(ControlStreamConnection.class);
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final ControlParser parser;
private boolean useInputDirectByteBuffers = true;
- private ByteBuffer buffer;
+ private RetainableByteBuffer buffer;
- public ControlStreamConnection(EndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, ControlParser parser)
+ public ControlStreamConnection(EndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool, ControlParser parser)
{
super(endPoint, executor);
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
this.parser = parser;
}
@@ -57,17 +58,18 @@ public class ControlStreamConnection extends AbstractConnection implements Conne
public void onUpgradeTo(ByteBuffer upgrade)
{
int capacity = Math.max(upgrade.remaining(), getInputBufferSize());
- buffer = byteBufferPool.acquire(capacity, isUseInputDirectByteBuffers());
- int position = BufferUtil.flipToFill(buffer);
- buffer.put(upgrade);
- BufferUtil.flipToFlush(buffer, position);
+ buffer = bufferPool.acquire(capacity, isUseInputDirectByteBuffers());
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ int position = BufferUtil.flipToFill(byteBuffer);
+ byteBuffer.put(upgrade);
+ BufferUtil.flipToFlush(byteBuffer, position);
}
@Override
public void onOpen()
{
super.onOpen();
- if (BufferUtil.hasContent(buffer))
+ if (buffer != null && buffer.hasRemaining())
onFillable();
else
fillInterested();
@@ -79,28 +81,28 @@ public class ControlStreamConnection extends AbstractConnection implements Conne
try
{
if (buffer == null)
- buffer = byteBufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
-
+ buffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
while (true)
{
// Parse first in case of bytes from the upgrade.
- parser.parse(buffer);
+ parser.parse(byteBuffer);
// Then read from the EndPoint.
- int filled = getEndPoint().fill(buffer);
+ int filled = getEndPoint().fill(byteBuffer);
if (LOG.isDebugEnabled())
LOG.debug("filled {} on {}", filled, this);
if (filled == 0)
{
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
fillInterested();
break;
}
else if (filled < 0)
{
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close();
break;
@@ -111,7 +113,7 @@ public class ControlStreamConnection extends AbstractConnection implements Conne
{
if (LOG.isDebugEnabled())
LOG.debug("could not process control stream {}", getEndPoint(), x);
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close(x);
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/DecoderStreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/DecoderStreamConnection.java
index 1c58aa6b2fa..cfff5bc350b 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/DecoderStreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/DecoderStreamConnection.java
@@ -18,8 +18,8 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
import org.eclipse.jetty.http3.qpack.QpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class DecoderStreamConnection extends InstructionStreamConnection
{
@@ -28,9 +28,9 @@ public class DecoderStreamConnection extends InstructionStreamConnection
private final QpackEncoder encoder;
- public DecoderStreamConnection(EndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, QpackEncoder encoder)
+ public DecoderStreamConnection(EndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool, QpackEncoder encoder)
{
- super(endPoint, executor, byteBufferPool);
+ super(endPoint, executor, bufferPool);
this.encoder = encoder;
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/EncoderStreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/EncoderStreamConnection.java
index 98985ea7c60..fbc29ce3f23 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/EncoderStreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/EncoderStreamConnection.java
@@ -18,8 +18,8 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
import org.eclipse.jetty.http3.qpack.QpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class EncoderStreamConnection extends InstructionStreamConnection
{
@@ -28,9 +28,9 @@ public class EncoderStreamConnection extends InstructionStreamConnection
private final QpackDecoder decoder;
- public EncoderStreamConnection(EndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, QpackDecoder decoder)
+ public EncoderStreamConnection(EndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool, QpackDecoder decoder)
{
- super(endPoint, executor, byteBufferPool);
+ super(endPoint, executor, bufferPool);
this.decoder = decoder;
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
index 21766cc042a..bafd858f8b4 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/HTTP3StreamConnection.java
@@ -27,7 +27,6 @@ import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.http3.internal.parser.MessageParser;
import org.eclipse.jetty.http3.internal.parser.ParserListener;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.RetainableByteBuffer;
import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
@@ -41,7 +40,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
private static final ByteBuffer EMPTY_DATA_FRAME = ByteBuffer.allocate(2);
private final AtomicReference action = new AtomicReference<>();
- private final RetainableByteBufferPool buffers;
+ private final RetainableByteBufferPool bufferPool;
private final MessageParser parser;
private boolean useInputDirectByteBuffers = true;
private HTTP3Stream stream;
@@ -49,10 +48,10 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
private boolean applicationMode;
private boolean remotelyClosed;
- public HTTP3StreamConnection(QuicStreamEndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, MessageParser parser)
+ public HTTP3StreamConnection(QuicStreamEndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool, MessageParser parser)
{
super(endPoint, executor);
- this.buffers = byteBufferPool.asRetainableByteBufferPool();
+ this.bufferPool = bufferPool;
this.parser = parser;
parser.init(MessageListener::new);
}
@@ -239,7 +238,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
{
if (networkBuffer == null)
{
- networkBuffer = buffers.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
+ networkBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
LOG.debug("acquired {}", networkBuffer);
}
@@ -270,7 +269,7 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
while (true)
{
- ByteBuffer byteBuffer = networkBuffer.getBuffer();
+ ByteBuffer byteBuffer = networkBuffer.getByteBuffer();
MessageParser.Result result = parser.parse(byteBuffer);
if (LOG.isDebugEnabled())
LOG.debug("parsed {} on {} with buffer {}", result, this, networkBuffer);
@@ -280,11 +279,11 @@ public abstract class HTTP3StreamConnection extends AbstractConnection
if (networkBuffer.isRetained())
{
networkBuffer.release();
- RetainableByteBuffer newBuffer = buffers.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
+ RetainableByteBuffer newBuffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
LOG.debug("reacquired {} for retained {}", newBuffer, networkBuffer);
networkBuffer = newBuffer;
- byteBuffer = networkBuffer.getBuffer();
+ byteBuffer = networkBuffer.getByteBuffer();
}
int filled = fill(byteBuffer);
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionFlusher.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionFlusher.java
index 9f746b0a5ec..d6808aa9523 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionFlusher.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionFlusher.java
@@ -20,9 +20,11 @@ import java.util.List;
import java.util.Queue;
import org.eclipse.jetty.http3.qpack.Instruction;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicSession;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
+import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.IteratingCallback;
import org.eclipse.jetty.util.thread.AutoLock;
import org.slf4j.Logger;
@@ -38,7 +40,8 @@ public class InstructionFlusher extends IteratingCallback
private final AutoLock lock = new AutoLock();
private final Queue queue = new ArrayDeque<>();
- private final ByteBufferPool.Lease lease;
+ private final RetainableByteBufferPool bufferPool;
+ private final RetainableByteBufferPool.Accumulator accumulator;
private final QuicStreamEndPoint endPoint;
private final long streamType;
private boolean initialized;
@@ -46,7 +49,8 @@ public class InstructionFlusher extends IteratingCallback
public InstructionFlusher(QuicSession session, QuicStreamEndPoint endPoint, long streamType)
{
- this.lease = new ByteBufferPool.Lease(session.getByteBufferPool());
+ this.bufferPool = session.getRetainableByteBufferPool();
+ this.accumulator = new RetainableByteBufferPool.Accumulator();
this.endPoint = endPoint;
this.streamType = streamType;
}
@@ -54,7 +58,7 @@ public class InstructionFlusher extends IteratingCallback
public boolean offer(List instructions)
{
Throwable closed;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
closed = terminated;
if (closed == null)
@@ -67,7 +71,7 @@ public class InstructionFlusher extends IteratingCallback
protected Action process()
{
List instructions;
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
if (queue.isEmpty())
return Action.IDLE;
@@ -78,20 +82,22 @@ public class InstructionFlusher extends IteratingCallback
if (LOG.isDebugEnabled())
LOG.debug("flushing {} on {}", instructions, this);
- instructions.forEach(i -> i.encode(lease));
+ instructions.forEach(i -> i.encode(accumulator));
if (!initialized)
{
initialized = true;
- ByteBuffer buffer = ByteBuffer.allocate(VarLenInt.length(streamType));
- VarLenInt.encode(buffer, streamType);
- buffer.flip();
- lease.insert(0, buffer, false);
+ RetainableByteBuffer buffer = bufferPool.acquire(VarLenInt.length(streamType), false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ VarLenInt.encode(byteBuffer, streamType);
+ byteBuffer.flip();
+ accumulator.insert(0, buffer);
}
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
if (LOG.isDebugEnabled())
- LOG.debug("writing {} buffers ({} bytes) on {}", buffers.size(), lease.getTotalLength(), this);
+ LOG.debug("writing {} buffers ({} bytes) on {}", buffers.size(), accumulator.getTotalLength(), this);
endPoint.write(this, buffers.toArray(ByteBuffer[]::new));
return Action.SCHEDULED;
}
@@ -100,9 +106,9 @@ public class InstructionFlusher extends IteratingCallback
public void succeeded()
{
if (LOG.isDebugEnabled())
- LOG.debug("succeeded to write {} on {}", lease.getByteBuffers(), this);
+ LOG.debug("succeeded to write {} buffers on {}", accumulator.getByteBuffers().size(), this);
- lease.recycle();
+ accumulator.release();
super.succeeded();
}
@@ -111,11 +117,11 @@ public class InstructionFlusher extends IteratingCallback
protected void onCompleteFailure(Throwable failure)
{
if (LOG.isDebugEnabled())
- LOG.debug("failed to write {} on {}", lease.getByteBuffers(), this, failure);
+ LOG.debug("failed to write {} buffers on {}", accumulator.getByteBuffers().size(), this, failure);
- lease.recycle();
+ accumulator.release();
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
terminated = failure;
queue.clear();
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionStreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionStreamConnection.java
index 24eaeed82b5..2f96607226e 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionStreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/InstructionStreamConnection.java
@@ -18,9 +18,10 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.http3.qpack.QpackException;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -28,14 +29,14 @@ import org.slf4j.LoggerFactory;
public abstract class InstructionStreamConnection extends AbstractConnection implements Connection.UpgradeTo
{
private static final Logger LOG = LoggerFactory.getLogger(InstructionStreamConnection.class);
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private boolean useInputDirectByteBuffers = true;
- private ByteBuffer buffer;
+ private RetainableByteBuffer buffer;
- public InstructionStreamConnection(EndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool)
+ public InstructionStreamConnection(EndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool)
{
super(endPoint, executor);
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
}
public boolean isUseInputDirectByteBuffers()
@@ -52,17 +53,18 @@ public abstract class InstructionStreamConnection extends AbstractConnection imp
public void onUpgradeTo(ByteBuffer upgrade)
{
int capacity = Math.max(upgrade.remaining(), getInputBufferSize());
- buffer = byteBufferPool.acquire(capacity, isUseInputDirectByteBuffers());
- int position = BufferUtil.flipToFill(buffer);
- buffer.put(upgrade);
- BufferUtil.flipToFlush(buffer, position);
+ buffer = bufferPool.acquire(capacity, isUseInputDirectByteBuffers());
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ int position = BufferUtil.flipToFill(byteBuffer);
+ byteBuffer.put(upgrade);
+ BufferUtil.flipToFlush(byteBuffer, position);
}
@Override
public void onOpen()
{
super.onOpen();
- if (BufferUtil.hasContent(buffer))
+ if (buffer != null && buffer.hasRemaining())
onFillable();
else
fillInterested();
@@ -74,28 +76,28 @@ public abstract class InstructionStreamConnection extends AbstractConnection imp
try
{
if (buffer == null)
- buffer = byteBufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
-
+ buffer = bufferPool.acquire(getInputBufferSize(), isUseInputDirectByteBuffers());
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
while (true)
{
// Parse first in case of bytes from the upgrade.
- parseInstruction(buffer);
+ parseInstruction(byteBuffer);
// Then read from the EndPoint.
- int filled = getEndPoint().fill(buffer);
+ int filled = getEndPoint().fill(byteBuffer);
if (LOG.isDebugEnabled())
LOG.debug("filled {} on {}", filled, this);
if (filled == 0)
{
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
fillInterested();
break;
}
else if (filled < 0)
{
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close();
break;
@@ -106,7 +108,7 @@ public abstract class InstructionStreamConnection extends AbstractConnection imp
{
if (LOG.isDebugEnabled())
LOG.debug("could not process decoder stream {}", getEndPoint(), x);
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close(x);
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/MessageFlusher.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/MessageFlusher.java
index ab8be1802ee..d19405c0414 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/MessageFlusher.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/MessageFlusher.java
@@ -21,7 +21,7 @@ import java.util.Queue;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.internal.generator.MessageGenerator;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.IteratingCallback;
@@ -35,19 +35,19 @@ public class MessageFlusher extends IteratingCallback
private final AutoLock lock = new AutoLock();
private final Queue entries = new ArrayDeque<>();
- private final ByteBufferPool.Lease lease;
+ private final RetainableByteBufferPool.Accumulator accumulator;
private final MessageGenerator generator;
private Entry entry;
- public MessageFlusher(ByteBufferPool byteBufferPool, QpackEncoder encoder, int maxHeadersLength, boolean useDirectByteBuffers)
+ public MessageFlusher(RetainableByteBufferPool bufferPool, QpackEncoder encoder, int maxHeadersLength, boolean useDirectByteBuffers)
{
- this.lease = new ByteBufferPool.Lease(byteBufferPool);
- this.generator = new MessageGenerator(encoder, maxHeadersLength, useDirectByteBuffers);
+ this.accumulator = new RetainableByteBufferPool.Accumulator();
+ this.generator = new MessageGenerator(bufferPool, encoder, maxHeadersLength, useDirectByteBuffers);
}
public boolean offer(QuicStreamEndPoint endPoint, Frame frame, Callback callback)
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
entries.offer(new Entry(endPoint, frame, callback));
}
@@ -57,7 +57,7 @@ public class MessageFlusher extends IteratingCallback
@Override
protected Action process()
{
- try (AutoLock l = lock.lock())
+ try (AutoLock ignored = lock.lock())
{
entry = entries.poll();
if (entry == null)
@@ -75,14 +75,14 @@ public class MessageFlusher extends IteratingCallback
return Action.SCHEDULED;
}
- int generated = generator.generate(lease, entry.endPoint.getStreamId(), frame, this::failed);
+ int generated = generator.generate(accumulator, entry.endPoint.getStreamId(), frame, this::failed);
if (generated < 0)
return Action.SCHEDULED;
QuicStreamEndPoint endPoint = entry.endPoint;
- List buffers = lease.getByteBuffers();
+ List buffers = accumulator.getByteBuffers();
if (LOG.isDebugEnabled())
- LOG.debug("writing {} buffers ({} bytes) for stream #{} on {}", buffers.size(), lease.getTotalLength(), endPoint.getStreamId(), this);
+ LOG.debug("writing {} buffers ({} bytes) for stream #{} on {}", buffers.size(), accumulator.getTotalLength(), endPoint.getStreamId(), this);
endPoint.write(this, buffers, Frame.isLast(frame));
return Action.SCHEDULED;
@@ -94,7 +94,7 @@ public class MessageFlusher extends IteratingCallback
if (LOG.isDebugEnabled())
LOG.debug("succeeded to write {} on {}", entry, this);
- lease.recycle();
+ accumulator.release();
entry.callback.succeeded();
entry = null;
@@ -108,7 +108,7 @@ public class MessageFlusher extends IteratingCallback
if (LOG.isDebugEnabled())
LOG.debug("failed to write {} on {}", entry, this, x);
- lease.recycle();
+ accumulator.release();
entry.callback.failed(x);
entry = null;
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/UnidirectionalStreamConnection.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/UnidirectionalStreamConnection.java
index 536668c0ffe..6bf48e18a6d 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/UnidirectionalStreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/UnidirectionalStreamConnection.java
@@ -21,11 +21,11 @@ import org.eclipse.jetty.http3.internal.parser.ParserListener;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
import org.eclipse.jetty.io.AbstractConnection;
-import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
import org.eclipse.jetty.quic.common.StreamType;
-import org.eclipse.jetty.util.BufferUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,18 +33,18 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
{
private static final Logger LOG = LoggerFactory.getLogger(UnidirectionalStreamConnection.class);
- private final ByteBufferPool byteBufferPool;
+ private final RetainableByteBufferPool bufferPool;
private final QpackEncoder encoder;
private final QpackDecoder decoder;
private final ParserListener listener;
private final VarLenInt parser = new VarLenInt();
private boolean useInputDirectByteBuffers = true;
- private ByteBuffer buffer;
+ private RetainableByteBuffer buffer;
- public UnidirectionalStreamConnection(QuicStreamEndPoint endPoint, Executor executor, ByteBufferPool byteBufferPool, QpackEncoder encoder, QpackDecoder decoder, ParserListener listener)
+ public UnidirectionalStreamConnection(QuicStreamEndPoint endPoint, Executor executor, RetainableByteBufferPool bufferPool, QpackEncoder encoder, QpackDecoder decoder, ParserListener listener)
{
super(endPoint, executor);
- this.byteBufferPool = byteBufferPool;
+ this.bufferPool = bufferPool;
this.encoder = encoder;
this.decoder = decoder;
this.listener = listener;
@@ -78,8 +78,8 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
{
int remaining = buffer.remaining();
ByteBuffer copy = buffer.isDirect() ? ByteBuffer.allocateDirect(remaining) : ByteBuffer.allocate(remaining);
- copy.put(buffer);
- byteBufferPool.release(buffer);
+ copy.put(buffer.getByteBuffer());
+ buffer.release();
buffer = null;
copy.flip();
return copy;
@@ -91,28 +91,28 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
try
{
if (buffer == null)
- buffer = byteBufferPool.acquire(2048, isUseInputDirectByteBuffers());
-
+ buffer = bufferPool.acquire(2048, isUseInputDirectByteBuffers());
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
while (true)
{
- int filled = getEndPoint().fill(buffer);
+ int filled = getEndPoint().fill(byteBuffer);
if (LOG.isDebugEnabled())
- LOG.debug("filled {} on {}: {}", filled, this, BufferUtil.toDetailString(buffer));
+ LOG.debug("filled {} on {}: {}", filled, this, buffer);
if (filled > 0)
{
- if (parser.decode(buffer, this::detectAndUpgrade))
+ if (parser.decode(byteBuffer, this::detectAndUpgrade))
break;
}
else if (filled == 0)
{
- byteBufferPool.release(buffer);
+ buffer.release();
fillInterested();
break;
}
else
{
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close();
break;
@@ -123,7 +123,7 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
{
if (LOG.isDebugEnabled())
LOG.debug("could not process stream {}", getEndPoint(), x);
- byteBufferPool.release(buffer);
+ buffer.release();
buffer = null;
getEndPoint().close(x);
}
@@ -134,7 +134,7 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
if (streamType == ControlStreamConnection.STREAM_TYPE)
{
ControlParser parser = new ControlParser(listener);
- ControlStreamConnection newConnection = new ControlStreamConnection(getEndPoint(), getExecutor(), byteBufferPool, parser);
+ ControlStreamConnection newConnection = new ControlStreamConnection(getEndPoint(), getExecutor(), bufferPool, parser);
newConnection.setInputBufferSize(getInputBufferSize());
newConnection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
@@ -143,7 +143,7 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
}
else if (streamType == EncoderStreamConnection.STREAM_TYPE)
{
- EncoderStreamConnection newConnection = new EncoderStreamConnection(getEndPoint(), getExecutor(), byteBufferPool, decoder);
+ EncoderStreamConnection newConnection = new EncoderStreamConnection(getEndPoint(), getExecutor(), bufferPool, decoder);
newConnection.setInputBufferSize(getInputBufferSize());
newConnection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
@@ -152,7 +152,7 @@ public class UnidirectionalStreamConnection extends AbstractConnection implement
}
else if (streamType == DecoderStreamConnection.STREAM_TYPE)
{
- DecoderStreamConnection newConnection = new DecoderStreamConnection(getEndPoint(), getExecutor(), byteBufferPool, encoder);
+ DecoderStreamConnection newConnection = new DecoderStreamConnection(getEndPoint(), getExecutor(), bufferPool, encoder);
newConnection.setInputBufferSize(getInputBufferSize());
newConnection.setUseInputDirectByteBuffers(isUseInputDirectByteBuffers());
if (LOG.isDebugEnabled())
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/CancelPushGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/CancelPushGenerator.java
index 464476625e8..50928293195 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/CancelPushGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/CancelPushGenerator.java
@@ -16,12 +16,17 @@ package org.eclipse.jetty.http3.internal.generator;
import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class CancelPushGenerator extends FrameGenerator
{
+ public CancelPushGenerator(RetainableByteBufferPool bufferPool)
+ {
+ super(bufferPool);
+ }
+
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
return 0;
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/ControlGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/ControlGenerator.java
index 002d7fc2b29..c1347dbe438 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/ControlGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/ControlGenerator.java
@@ -17,22 +17,22 @@ import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.frames.FrameType;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class ControlGenerator
{
private final FrameGenerator[] generators = new FrameGenerator[FrameType.maxType() + 1];
- public ControlGenerator(boolean useDirectByteBuffers)
+ public ControlGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
- generators[FrameType.CANCEL_PUSH.type()] = new CancelPushGenerator();
- generators[FrameType.SETTINGS.type()] = new SettingsGenerator(useDirectByteBuffers);
- generators[FrameType.GOAWAY.type()] = new GoAwayGenerator(useDirectByteBuffers);
- generators[FrameType.MAX_PUSH_ID.type()] = new MaxPushIdGenerator();
+ generators[FrameType.CANCEL_PUSH.type()] = new CancelPushGenerator(bufferPool);
+ generators[FrameType.SETTINGS.type()] = new SettingsGenerator(bufferPool, useDirectByteBuffers);
+ generators[FrameType.GOAWAY.type()] = new GoAwayGenerator(bufferPool, useDirectByteBuffers);
+ generators[FrameType.MAX_PUSH_ID.type()] = new MaxPushIdGenerator(bufferPool);
}
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
- return generators[frame.getFrameType().type()].generate(lease, streamId, frame, fail);
+ return generators[frame.getFrameType().type()].generate(accumulator, streamId, frame, fail);
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/DataGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/DataGenerator.java
index 46e07ca2a7e..ec1909c30fc 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/DataGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/DataGenerator.java
@@ -20,35 +20,40 @@ import org.eclipse.jetty.http3.frames.DataFrame;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.frames.FrameType;
import org.eclipse.jetty.http3.internal.VarLenInt;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public class DataGenerator extends FrameGenerator
{
private final boolean useDirectByteBuffers;
- public DataGenerator(boolean useDirectByteBuffers)
+ public DataGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
+ super(bufferPool);
this.useDirectByteBuffers = useDirectByteBuffers;
}
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
DataFrame dataFrame = (DataFrame)frame;
- return generateDataFrame(lease, dataFrame);
+ return generateDataFrame(accumulator, dataFrame);
}
- private int generateDataFrame(ByteBufferPool.Lease lease, DataFrame frame)
+ private int generateDataFrame(RetainableByteBufferPool.Accumulator accumulator, DataFrame frame)
{
ByteBuffer data = frame.getByteBuffer();
int dataLength = data.remaining();
int headerLength = VarLenInt.length(FrameType.DATA.type()) + VarLenInt.length(dataLength);
- ByteBuffer header = lease.acquire(headerLength, useDirectByteBuffers);
- VarLenInt.encode(header, FrameType.DATA.type());
- VarLenInt.encode(header, dataLength);
- header.flip();
- lease.append(header, true);
- lease.append(data, false);
+ RetainableByteBuffer header = getRetainableByteBufferPool().acquire(headerLength, useDirectByteBuffers);
+ ByteBuffer byteBuffer = header.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ VarLenInt.encode(byteBuffer, FrameType.DATA.type());
+ VarLenInt.encode(byteBuffer, dataLength);
+ byteBuffer.flip();
+ accumulator.append(header);
+ accumulator.append(RetainableByteBuffer.wrap(data));
return headerLength + dataLength;
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/FrameGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/FrameGenerator.java
index 1dbf3c9eeef..c8621209c0c 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/FrameGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/FrameGenerator.java
@@ -16,9 +16,21 @@ package org.eclipse.jetty.http3.internal.generator;
import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public abstract class FrameGenerator
{
- public abstract int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail);
+ private final RetainableByteBufferPool bufferPool;
+
+ public FrameGenerator(RetainableByteBufferPool bufferPool)
+ {
+ this.bufferPool = bufferPool;
+ }
+
+ public RetainableByteBufferPool getRetainableByteBufferPool()
+ {
+ return bufferPool;
+ }
+
+ public abstract int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail);
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/GoAwayGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/GoAwayGenerator.java
index 2d67c63c0c3..97715c2249f 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/GoAwayGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/GoAwayGenerator.java
@@ -20,35 +20,40 @@ import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.frames.FrameType;
import org.eclipse.jetty.http3.frames.GoAwayFrame;
import org.eclipse.jetty.http3.internal.VarLenInt;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public class GoAwayGenerator extends FrameGenerator
{
private final boolean useDirectByteBuffers;
- public GoAwayGenerator(boolean useDirectByteBuffers)
+ public GoAwayGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
+ super(bufferPool);
this.useDirectByteBuffers = useDirectByteBuffers;
}
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
GoAwayFrame goAwayFrame = (GoAwayFrame)frame;
- return generateGoAwayFrame(lease, goAwayFrame);
+ return generateGoAwayFrame(accumulator, goAwayFrame);
}
- private int generateGoAwayFrame(ByteBufferPool.Lease lease, GoAwayFrame frame)
+ private int generateGoAwayFrame(RetainableByteBufferPool.Accumulator accumulator, GoAwayFrame frame)
{
long lastId = frame.getLastId();
int lastIdLength = VarLenInt.length(lastId);
int length = VarLenInt.length(FrameType.GOAWAY.type()) + VarLenInt.length(lastIdLength) + lastIdLength;
- ByteBuffer buffer = lease.acquire(length, useDirectByteBuffers);
- VarLenInt.encode(buffer, FrameType.GOAWAY.type());
- VarLenInt.encode(buffer, lastIdLength);
- VarLenInt.encode(buffer, lastId);
- buffer.flip();
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(length, useDirectByteBuffers);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ VarLenInt.encode(byteBuffer, FrameType.GOAWAY.type());
+ VarLenInt.encode(byteBuffer, lastIdLength);
+ VarLenInt.encode(byteBuffer, lastId);
+ byteBuffer.flip();
+ accumulator.append(buffer);
return length;
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/HeadersGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/HeadersGenerator.java
index fcfe269811f..b27784d89da 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/HeadersGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/HeadersGenerator.java
@@ -22,7 +22,9 @@ import org.eclipse.jetty.http3.frames.HeadersFrame;
import org.eclipse.jetty.http3.internal.VarLenInt;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
import org.eclipse.jetty.http3.qpack.QpackException;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+import org.eclipse.jetty.util.BufferUtil;
public class HeadersGenerator extends FrameGenerator
{
@@ -30,21 +32,22 @@ public class HeadersGenerator extends FrameGenerator
private final int maxLength;
private final boolean useDirectByteBuffers;
- public HeadersGenerator(QpackEncoder encoder, int maxLength, boolean useDirectByteBuffers)
+ public HeadersGenerator(RetainableByteBufferPool bufferPool, QpackEncoder encoder, int maxLength, boolean useDirectByteBuffers)
{
+ super(bufferPool);
this.encoder = encoder;
this.maxLength = maxLength;
this.useDirectByteBuffers = useDirectByteBuffers;
}
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
HeadersFrame headersFrame = (HeadersFrame)frame;
- return generateHeadersFrame(lease, streamId, headersFrame, fail);
+ return generateHeadersFrame(accumulator, streamId, headersFrame, fail);
}
- private int generateHeadersFrame(ByteBufferPool.Lease lease, long streamId, HeadersFrame frame, Consumer fail)
+ private int generateHeadersFrame(RetainableByteBufferPool.Accumulator accumulator, long streamId, HeadersFrame frame, Consumer fail)
{
try
{
@@ -52,21 +55,23 @@ public class HeadersGenerator extends FrameGenerator
int frameTypeLength = VarLenInt.length(FrameType.HEADERS.type());
int maxHeaderLength = frameTypeLength + VarLenInt.MAX_LENGTH;
// The capacity of the buffer is larger than maxLength, but we need to enforce at most maxLength.
- ByteBuffer buffer = lease.acquire(maxHeaderLength + maxLength, useDirectByteBuffers);
- buffer.position(maxHeaderLength);
- buffer.limit(buffer.position() + maxLength);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(maxHeaderLength + maxLength, useDirectByteBuffers);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.position(maxHeaderLength);
+ byteBuffer.limit(byteBuffer.position() + maxLength);
// Encode after the maxHeaderLength.
- encoder.encode(buffer, streamId, frame.getMetaData());
- buffer.flip();
- buffer.position(maxHeaderLength);
+ encoder.encode(byteBuffer, streamId, frame.getMetaData());
+ byteBuffer.flip();
+ byteBuffer.position(maxHeaderLength);
int dataLength = buffer.remaining();
int headerLength = frameTypeLength + VarLenInt.length(dataLength);
- int position = buffer.position() - headerLength;
- buffer.position(position);
- VarLenInt.encode(buffer, FrameType.HEADERS.type());
- VarLenInt.encode(buffer, dataLength);
- buffer.position(position);
- lease.append(buffer, true);
+ int position = byteBuffer.position() - headerLength;
+ byteBuffer.position(position);
+ VarLenInt.encode(byteBuffer, FrameType.HEADERS.type());
+ VarLenInt.encode(byteBuffer, dataLength);
+ byteBuffer.position(position);
+ accumulator.append(buffer);
return headerLength + dataLength;
}
catch (QpackException x)
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MaxPushIdGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MaxPushIdGenerator.java
index ee132a0d9ea..323bbdf29c9 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MaxPushIdGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MaxPushIdGenerator.java
@@ -16,12 +16,17 @@ package org.eclipse.jetty.http3.internal.generator;
import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class MaxPushIdGenerator extends FrameGenerator
{
+ public MaxPushIdGenerator(RetainableByteBufferPool bufferPool)
+ {
+ super(bufferPool);
+ }
+
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
return 0;
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MessageGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MessageGenerator.java
index 8b6330cc971..a0339f7d344 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MessageGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/MessageGenerator.java
@@ -18,21 +18,21 @@ import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.frames.FrameType;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class MessageGenerator
{
private final FrameGenerator[] generators = new FrameGenerator[FrameType.maxType() + 1];
- public MessageGenerator(QpackEncoder encoder, int maxHeadersLength, boolean useDirectByteBuffers)
+ public MessageGenerator(RetainableByteBufferPool bufferPool, QpackEncoder encoder, int maxHeadersLength, boolean useDirectByteBuffers)
{
- generators[FrameType.DATA.type()] = new DataGenerator(useDirectByteBuffers);
- generators[FrameType.HEADERS.type()] = new HeadersGenerator(encoder, maxHeadersLength, useDirectByteBuffers);
- generators[FrameType.PUSH_PROMISE.type()] = new PushPromiseGenerator();
+ generators[FrameType.DATA.type()] = new DataGenerator(bufferPool, useDirectByteBuffers);
+ generators[FrameType.HEADERS.type()] = new HeadersGenerator(bufferPool, encoder, maxHeadersLength, useDirectByteBuffers);
+ generators[FrameType.PUSH_PROMISE.type()] = new PushPromiseGenerator(bufferPool);
}
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
- return generators[frame.getFrameType().type()].generate(lease, streamId, frame, fail);
+ return generators[frame.getFrameType().type()].generate(accumulator, streamId, frame, fail);
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/PushPromiseGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/PushPromiseGenerator.java
index 0acfb70bec8..2a849106681 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/PushPromiseGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/PushPromiseGenerator.java
@@ -16,12 +16,17 @@ package org.eclipse.jetty.http3.internal.generator;
import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public class PushPromiseGenerator extends FrameGenerator
{
+ public PushPromiseGenerator(RetainableByteBufferPool bufferPool)
+ {
+ super(bufferPool);
+ }
+
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
return 0;
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/SettingsGenerator.java b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/SettingsGenerator.java
index 12a5f18b814..6e200195e75 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/SettingsGenerator.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/main/java/org/eclipse/jetty/http3/internal/generator/SettingsGenerator.java
@@ -20,26 +20,28 @@ import java.util.function.Consumer;
import org.eclipse.jetty.http3.frames.Frame;
import org.eclipse.jetty.http3.frames.SettingsFrame;
import org.eclipse.jetty.http3.internal.VarLenInt;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
public class SettingsGenerator extends FrameGenerator
{
private final boolean useDirectByteBuffers;
- public SettingsGenerator(boolean useDirectByteBuffers)
+ public SettingsGenerator(RetainableByteBufferPool bufferPool, boolean useDirectByteBuffers)
{
+ super(bufferPool);
this.useDirectByteBuffers = useDirectByteBuffers;
}
@Override
- public int generate(ByteBufferPool.Lease lease, long streamId, Frame frame, Consumer fail)
+ public int generate(RetainableByteBufferPool.Accumulator accumulator, long streamId, Frame frame, Consumer fail)
{
SettingsFrame settingsFrame = (SettingsFrame)frame;
- return generateSettings(lease, settingsFrame);
+ return generateSettings(accumulator, settingsFrame);
}
- private int generateSettings(ByteBufferPool.Lease lease, SettingsFrame frame)
+ private int generateSettings(RetainableByteBufferPool.Accumulator accumulator, SettingsFrame frame)
{
int length = 0;
Map settings = frame.getSettings();
@@ -48,16 +50,18 @@ public class SettingsGenerator extends FrameGenerator
length += VarLenInt.length(e.getKey()) + VarLenInt.length(e.getValue());
}
int capacity = VarLenInt.length(frame.getFrameType().type()) + VarLenInt.length(length) + length;
- ByteBuffer buffer = lease.acquire(capacity, useDirectByteBuffers);
- VarLenInt.encode(buffer, frame.getFrameType().type());
- VarLenInt.encode(buffer, length);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(capacity, useDirectByteBuffers);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ VarLenInt.encode(byteBuffer, frame.getFrameType().type());
+ VarLenInt.encode(byteBuffer, length);
for (Map.Entry e : settings.entrySet())
{
- VarLenInt.encode(buffer, e.getKey());
- VarLenInt.encode(buffer, e.getValue());
+ VarLenInt.encode(byteBuffer, e.getKey());
+ VarLenInt.encode(byteBuffer, e.getValue());
}
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
return capacity;
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/DataGenerateParseTest.java b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/DataGenerateParseTest.java
index 9e2f65bdd36..3adbb3c5454 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/DataGenerateParseTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/DataGenerateParseTest.java
@@ -23,7 +23,7 @@ import org.eclipse.jetty.http3.frames.DataFrame;
import org.eclipse.jetty.http3.internal.generator.MessageGenerator;
import org.eclipse.jetty.http3.internal.parser.MessageParser;
import org.eclipse.jetty.http3.internal.parser.ParserListener;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.Test;
@@ -53,8 +53,9 @@ public class DataGenerateParseTest
byteBuffer.get(inputBytes);
DataFrame input = new DataFrame(ByteBuffer.wrap(inputBytes), true);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
- new MessageGenerator(null, 8192, true).generate(lease, 0, input, null);
+ RetainableByteBufferPool.NonPooling bufferPool = new RetainableByteBufferPool.NonPooling();
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ new MessageGenerator(bufferPool, null, 8192, true).generate(accumulator, 0, input, null);
List frames = new ArrayList<>();
MessageParser parser = new MessageParser(new ParserListener()
@@ -66,7 +67,7 @@ public class DataGenerateParseTest
}
}, null, 13, () -> true);
parser.init(UnaryOperator.identity());
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/GoAwayGenerateParseTest.java b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/GoAwayGenerateParseTest.java
index 315d2051078..d0eae5c137c 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/GoAwayGenerateParseTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/GoAwayGenerateParseTest.java
@@ -21,7 +21,7 @@ import org.eclipse.jetty.http3.frames.GoAwayFrame;
import org.eclipse.jetty.http3.internal.generator.ControlGenerator;
import org.eclipse.jetty.http3.internal.parser.ControlParser;
import org.eclipse.jetty.http3.internal.parser.ParserListener;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -34,8 +34,9 @@ public class GoAwayGenerateParseTest
{
GoAwayFrame input = GoAwayFrame.CLIENT_GRACEFUL;
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
- new ControlGenerator(true).generate(lease, 0, input, null);
+ RetainableByteBufferPool.NonPooling bufferPool = new RetainableByteBufferPool.NonPooling();
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ new ControlGenerator(bufferPool, true).generate(accumulator, 0, input, null);
List frames = new ArrayList<>();
ControlParser parser = new ControlParser(new ParserListener()
@@ -46,7 +47,7 @@ public class GoAwayGenerateParseTest
frames.add(frame);
}
});
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/HeadersGenerateParseTest.java b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/HeadersGenerateParseTest.java
index 6230acfa41b..436c8799899 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/HeadersGenerateParseTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/HeadersGenerateParseTest.java
@@ -29,7 +29,7 @@ import org.eclipse.jetty.http3.internal.parser.MessageParser;
import org.eclipse.jetty.http3.internal.parser.ParserListener;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -46,11 +46,12 @@ public class HeadersGenerateParseTest
.put("Cookie", "c=d");
HeadersFrame input = new HeadersFrame(new MetaData.Request(HttpMethod.GET.asString(), uri, HttpVersion.HTTP_3, fields), true);
- QpackEncoder encoder = new QpackEncoder(instructions -> {}, 100);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
- new MessageGenerator(encoder, 8192, true).generate(lease, 0, input, null);
+ RetainableByteBufferPool.NonPooling bufferPool = new RetainableByteBufferPool.NonPooling();
+ QpackEncoder encoder = new QpackEncoder(bufferPool, instructions -> {}, 100);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ new MessageGenerator(bufferPool, encoder, 8192, true).generate(accumulator, 0, input, null);
- QpackDecoder decoder = new QpackDecoder(instructions -> {}, 8192);
+ QpackDecoder decoder = new QpackDecoder(bufferPool, instructions -> {}, 8192);
List frames = new ArrayList<>();
MessageParser parser = new MessageParser(new ParserListener()
{
@@ -61,7 +62,7 @@ public class HeadersGenerateParseTest
}
}, decoder, 13, () -> true);
parser.init(UnaryOperator.identity());
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
diff --git a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/SettingsGenerateParseTest.java b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/SettingsGenerateParseTest.java
index 53e8c70402a..7af1c72f48a 100644
--- a/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/SettingsGenerateParseTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-common/src/test/java/org/eclipse/jetty/http3/internal/SettingsGenerateParseTest.java
@@ -22,7 +22,7 @@ import org.eclipse.jetty.http3.frames.SettingsFrame;
import org.eclipse.jetty.http3.internal.generator.ControlGenerator;
import org.eclipse.jetty.http3.internal.parser.ControlParser;
import org.eclipse.jetty.http3.internal.parser.ParserListener;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -46,8 +46,9 @@ public class SettingsGenerateParseTest
{
SettingsFrame input = new SettingsFrame(settings);
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
- new ControlGenerator(true).generate(lease, 0, input, null);
+ RetainableByteBufferPool.NonPooling bufferPool = new RetainableByteBufferPool.NonPooling();
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ new ControlGenerator(bufferPool, true).generate(accumulator, 0, input, null);
List frames = new ArrayList<>();
ControlParser parser = new ControlParser(new ParserListener()
@@ -58,7 +59,7 @@ public class SettingsGenerateParseTest
frames.add(frame);
}
});
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
parser.parse(buffer);
assertFalse(buffer.hasRemaining());
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/Instruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/Instruction.java
index b3f472184c6..66824705efa 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/Instruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/Instruction.java
@@ -15,11 +15,11 @@ package org.eclipse.jetty.http3.qpack;
import java.util.List;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
public interface Instruction
{
- void encode(ByteBufferPool.Lease lease);
+ void encode(RetainableByteBufferPool.Accumulator accumulator);
/**
*
A handler for instructions issued by an {@link QpackEncoder} or {@link QpackDecoder}.
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java
index ca2cecb584f..9c667a1a7fb 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackDecoder.java
@@ -34,6 +34,7 @@ import org.eclipse.jetty.http3.qpack.internal.table.DynamicTable;
import org.eclipse.jetty.http3.qpack.internal.table.Entry;
import org.eclipse.jetty.http3.qpack.internal.table.StaticTable;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerParser;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.component.Dumpable;
import org.slf4j.Logger;
@@ -55,6 +56,7 @@ public class QpackDecoder implements Dumpable
private final NBitIntegerParser _integerDecoder = new NBitIntegerParser();
private final InstructionHandler _instructionHandler = new InstructionHandler();
private final Map _blockedStreams = new HashMap<>();
+ private final RetainableByteBufferPool _bufferPool;
private int _maxHeaderSize;
private int _maxBlockedStreams;
@@ -80,14 +82,20 @@ public class QpackDecoder implements Dumpable
/**
* @param maxHeaderSize The maximum allowed size of a headers block, expressed as total of all name and value characters, plus 32 per field
*/
- public QpackDecoder(Instruction.Handler handler, int maxHeaderSize)
+ public QpackDecoder(RetainableByteBufferPool bufferPool, Instruction.Handler handler, int maxHeaderSize)
{
+ _bufferPool = bufferPool;
_context = new QpackContext();
_handler = handler;
_parser = new DecoderInstructionParser(_instructionHandler);
_maxHeaderSize = maxHeaderSize;
}
+ public RetainableByteBufferPool getRetainableByteBufferPool()
+ {
+ return _bufferPool;
+ }
+
QpackContext getQpackContext()
{
return _context;
@@ -171,7 +179,7 @@ public class QpackDecoder implements Dumpable
LOG.debug("Decoded: streamId={}, metadata={}", streamId, metaData);
_metaDataNotifications.add(new MetaDataNotification(streamId, metaData, handler));
if (requiredInsertCount > 0)
- _instructions.add(new SectionAcknowledgmentInstruction(streamId));
+ _instructions.add(new SectionAcknowledgmentInstruction(_bufferPool, streamId));
}
else
{
@@ -237,7 +245,7 @@ public class QpackDecoder implements Dumpable
_encodedFieldSections.removeIf(encodedFieldSection -> encodedFieldSection.getStreamId() == streamId);
_blockedStreams.remove(streamId);
_metaDataNotifications.removeIf(notification -> notification._streamId == streamId);
- _instructions.add(new StreamCancellationInstruction(streamId));
+ _instructions.add(new StreamCancellationInstruction(_bufferPool, streamId));
notifyInstructionHandler();
}
@@ -261,7 +269,7 @@ public class QpackDecoder implements Dumpable
_metaDataNotifications.add(new MetaDataNotification(streamId, metaData, encodedFieldSection.getHandler()));
if (requiredInsertCount > 0)
- _instructions.add(new SectionAcknowledgmentInstruction(streamId));
+ _instructions.add(new SectionAcknowledgmentInstruction(_bufferPool, streamId));
}
}
}
@@ -352,7 +360,7 @@ public class QpackDecoder implements Dumpable
// Add the new Entry to the DynamicTable.
Entry entry = new Entry(referencedEntry.getHttpField());
dynamicTable.add(entry);
- _instructions.add(new InsertCountIncrementInstruction(1));
+ _instructions.add(new InsertCountIncrementInstruction(_bufferPool, 1));
checkEncodedFieldSections();
}
@@ -369,7 +377,7 @@ public class QpackDecoder implements Dumpable
// Add the new Entry to the DynamicTable.
Entry entry = new Entry(new HttpField(referencedEntry.getHttpField().getHeader(), referencedEntry.getHttpField().getName(), value));
dynamicTable.add(entry);
- _instructions.add(new InsertCountIncrementInstruction(1));
+ _instructions.add(new InsertCountIncrementInstruction(_bufferPool, 1));
checkEncodedFieldSections();
}
@@ -384,7 +392,7 @@ public class QpackDecoder implements Dumpable
// Add the new Entry to the DynamicTable.
DynamicTable dynamicTable = _context.getDynamicTable();
dynamicTable.add(entry);
- _instructions.add(new InsertCountIncrementInstruction(1));
+ _instructions.add(new InsertCountIncrementInstruction(_bufferPool, 1));
checkEncodedFieldSections();
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java
index d8427466f9c..190a6706320 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/QpackEncoder.java
@@ -38,6 +38,7 @@ import org.eclipse.jetty.http3.qpack.internal.parser.EncoderInstructionParser;
import org.eclipse.jetty.http3.qpack.internal.table.DynamicTable;
import org.eclipse.jetty.http3.qpack.internal.table.Entry;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.thread.AutoLock;
@@ -89,6 +90,7 @@ public class QpackEncoder implements Dumpable
private final AutoLock lock = new AutoLock();
private final List _instructions = new ArrayList<>();
+ private final RetainableByteBufferPool _bufferPool;
private final Instruction.Handler _handler;
private final QpackContext _context;
private int _maxBlockedStreams;
@@ -98,14 +100,20 @@ public class QpackEncoder implements Dumpable
private int _knownInsertCount = 0;
private int _blockedStreams = 0;
- public QpackEncoder(Instruction.Handler handler, int maxBlockedStreams)
+ public QpackEncoder(RetainableByteBufferPool bufferPool, Instruction.Handler handler, int maxBlockedStreams)
{
+ _bufferPool = bufferPool;
_handler = handler;
_context = new QpackContext();
_maxBlockedStreams = maxBlockedStreams;
_parser = new EncoderInstructionParser(_instructionHandler);
}
+ public RetainableByteBufferPool getRetainableByteBufferPool()
+ {
+ return _bufferPool;
+ }
+
Map getStreamInfoMap()
{
return _streamInfoMap;
@@ -134,7 +142,7 @@ public class QpackEncoder implements Dumpable
public void setCapacity(int capacity)
{
_context.getDynamicTable().setCapacity(capacity);
- _handler.onInstructions(List.of(new SetCapacityInstruction(capacity)));
+ _handler.onInstructions(List.of(new SetCapacityInstruction(_bufferPool, capacity)));
notifyInstructionHandler();
}
@@ -294,7 +302,7 @@ public class QpackEncoder implements Dumpable
{
int index = _context.indexOf(entry);
dynamicTable.add(new Entry(field));
- _instructions.add(new DuplicateInstruction(index));
+ _instructions.add(new DuplicateInstruction(_bufferPool, index));
notifyInstructionHandler();
return true;
}
@@ -306,14 +314,14 @@ public class QpackEncoder implements Dumpable
{
int index = _context.indexOf(nameEntry);
dynamicTable.add(new Entry(field));
- _instructions.add(new IndexedNameEntryInstruction(!nameEntry.isStatic(), index, huffman, field.getValue()));
+ _instructions.add(new IndexedNameEntryInstruction(_bufferPool, !nameEntry.isStatic(), index, huffman, field.getValue()));
notifyInstructionHandler();
return true;
}
// Add the entry without referencing an existing entry.
dynamicTable.add(new Entry(field));
- _instructions.add(new LiteralNameEntryInstruction(field, huffman));
+ _instructions.add(new LiteralNameEntryInstruction(_bufferPool, field, huffman));
notifyInstructionHandler();
return true;
}
@@ -366,7 +374,7 @@ public class QpackEncoder implements Dumpable
int index = _context.indexOf(entry);
Entry newEntry = new Entry(field);
dynamicTable.add(newEntry);
- _instructions.add(new DuplicateInstruction(index));
+ _instructions.add(new DuplicateInstruction(_bufferPool, index));
// Should we reference this entry and risk blocking.
if (referenceEntry(newEntry, streamInfo))
@@ -384,7 +392,7 @@ public class QpackEncoder implements Dumpable
int index = _context.indexOf(nameEntry);
Entry newEntry = new Entry(field);
dynamicTable.add(newEntry);
- _instructions.add(new IndexedNameEntryInstruction(!nameEntry.isStatic(), index, huffman, field.getValue()));
+ _instructions.add(new IndexedNameEntryInstruction(_bufferPool, !nameEntry.isStatic(), index, huffman, field.getValue()));
// Should we reference this entry and risk blocking.
if (referenceEntry(newEntry, streamInfo))
@@ -399,7 +407,7 @@ public class QpackEncoder implements Dumpable
{
Entry newEntry = new Entry(field);
dynamicTable.add(newEntry);
- _instructions.add(new LiteralNameEntryInstruction(field, huffman));
+ _instructions.add(new LiteralNameEntryInstruction(_bufferPool, field, huffman));
// Should we reference this entry and risk blocking.
if (referenceEntry(newEntry, streamInfo))
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/AbstractInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/AbstractInstruction.java
new file mode 100644
index 00000000000..277d66e87d1
--- /dev/null
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/AbstractInstruction.java
@@ -0,0 +1,32 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.http3.qpack.internal.instruction;
+
+import org.eclipse.jetty.http3.qpack.Instruction;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
+
+public abstract class AbstractInstruction implements Instruction
+{
+ private final RetainableByteBufferPool bufferPool;
+
+ protected AbstractInstruction(RetainableByteBufferPool bufferPool)
+ {
+ this.bufferPool = bufferPool;
+ }
+
+ public RetainableByteBufferPool getRetainableByteBufferPool()
+ {
+ return bufferPool;
+ }
+}
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/DuplicateInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/DuplicateInstruction.java
index 8d88d81c2bc..f9c6e362229 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/DuplicateInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/DuplicateInstruction.java
@@ -15,17 +15,18 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class DuplicateInstruction implements Instruction
+public class DuplicateInstruction extends AbstractInstruction
{
private final int _index;
- public DuplicateInstruction(int index)
+ public DuplicateInstruction(RetainableByteBufferPool bufferPool, int index)
{
+ super(bufferPool);
_index = index;
}
@@ -35,14 +36,16 @@ public class DuplicateInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(5, _index) + 1;
- ByteBuffer buffer = lease.acquire(size, false);
- buffer.put((byte)0x00);
- NBitIntegerEncoder.encode(buffer, 5, _index);
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.put((byte)0x00);
+ NBitIntegerEncoder.encode(byteBuffer, 5, _index);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/IndexedNameEntryInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/IndexedNameEntryInstruction.java
index 68da23fa120..0e66dd59652 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/IndexedNameEntryInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/IndexedNameEntryInstruction.java
@@ -15,21 +15,22 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.HuffmanEncoder;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class IndexedNameEntryInstruction implements Instruction
+public class IndexedNameEntryInstruction extends AbstractInstruction
{
private final boolean _dynamic;
private final int _index;
private final boolean _huffman;
private final String _value;
- public IndexedNameEntryInstruction(boolean dynamic, int index, boolean huffman, String value)
+ public IndexedNameEntryInstruction(RetainableByteBufferPool bufferPool, boolean dynamic, int index, boolean huffman, String value)
{
+ super(bufferPool);
_dynamic = dynamic;
_index = index;
_huffman = huffman;
@@ -52,31 +53,33 @@ public class IndexedNameEntryInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(6, _index) + (_huffman ? HuffmanEncoder.octetsNeeded(_value) : _value.length()) + 2;
- ByteBuffer buffer = lease.acquire(size, false);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
// First bit indicates the instruction, second bit is whether it is a dynamic table reference or not.
- buffer.put((byte)(0x80 | (_dynamic ? 0x00 : 0x40)));
- NBitIntegerEncoder.encode(buffer, 6, _index);
+ byteBuffer.put((byte)(0x80 | (_dynamic ? 0x00 : 0x40)));
+ NBitIntegerEncoder.encode(byteBuffer, 6, _index);
// We will not huffman encode the string.
if (_huffman)
{
- buffer.put((byte)(0x80));
- NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeeded(_value));
- HuffmanEncoder.encode(buffer, _value);
+ byteBuffer.put((byte)(0x80));
+ NBitIntegerEncoder.encode(byteBuffer, 7, HuffmanEncoder.octetsNeeded(_value));
+ HuffmanEncoder.encode(byteBuffer, _value);
}
else
{
- buffer.put((byte)(0x00));
- NBitIntegerEncoder.encode(buffer, 7, _value.length());
- buffer.put(_value.getBytes());
+ byteBuffer.put((byte)(0x00));
+ NBitIntegerEncoder.encode(byteBuffer, 7, _value.length());
+ byteBuffer.put(_value.getBytes());
}
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/InsertCountIncrementInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/InsertCountIncrementInstruction.java
index d9b02db55f4..5bff85dc91e 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/InsertCountIncrementInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/InsertCountIncrementInstruction.java
@@ -15,17 +15,18 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class InsertCountIncrementInstruction implements Instruction
+public class InsertCountIncrementInstruction extends AbstractInstruction
{
private final int _increment;
- public InsertCountIncrementInstruction(int increment)
+ public InsertCountIncrementInstruction(RetainableByteBufferPool bufferPool, int increment)
{
+ super(bufferPool);
_increment = increment;
}
@@ -35,14 +36,16 @@ public class InsertCountIncrementInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(6, _increment) + 1;
- ByteBuffer buffer = lease.acquire(size, false);
- buffer.put((byte)0x00);
- NBitIntegerEncoder.encode(buffer, 6, _increment);
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.put((byte)0x00);
+ NBitIntegerEncoder.encode(byteBuffer, 6, _increment);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/LiteralNameEntryInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/LiteralNameEntryInstruction.java
index 623951545f4..a2c2c5c26dd 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/LiteralNameEntryInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/LiteralNameEntryInstruction.java
@@ -16,26 +16,27 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.HttpField;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.HuffmanEncoder;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class LiteralNameEntryInstruction implements Instruction
+public class LiteralNameEntryInstruction extends AbstractInstruction
{
private final boolean _huffmanName;
private final boolean _huffmanValue;
private final String _name;
private final String _value;
- public LiteralNameEntryInstruction(HttpField httpField, boolean huffman)
+ public LiteralNameEntryInstruction(RetainableByteBufferPool bufferPool, HttpField httpField, boolean huffman)
{
- this(httpField, huffman, huffman);
+ this(bufferPool, httpField, huffman, huffman);
}
- public LiteralNameEntryInstruction(HttpField httpField, boolean huffmanName, boolean huffmanValue)
+ public LiteralNameEntryInstruction(RetainableByteBufferPool bufferPool, HttpField httpField, boolean huffmanName, boolean huffmanValue)
{
+ super(bufferPool);
_huffmanName = huffmanName;
_huffmanValue = huffmanValue;
_name = httpField.getName();
@@ -53,40 +54,42 @@ public class LiteralNameEntryInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = (_huffmanName ? HuffmanEncoder.octetsNeeded(_name) : _name.length()) +
(_huffmanValue ? HuffmanEncoder.octetsNeeded(_value) : _value.length()) + 2;
- ByteBuffer buffer = lease.acquire(size, false);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
if (_huffmanName)
{
- buffer.put((byte)(0x40 | 0x20));
- NBitIntegerEncoder.encode(buffer, 5, HuffmanEncoder.octetsNeeded(_name));
- HuffmanEncoder.encode(buffer, _name);
+ byteBuffer.put((byte)(0x40 | 0x20));
+ NBitIntegerEncoder.encode(byteBuffer, 5, HuffmanEncoder.octetsNeeded(_name));
+ HuffmanEncoder.encode(byteBuffer, _name);
}
else
{
- buffer.put((byte)(0x40));
- NBitIntegerEncoder.encode(buffer, 5, _name.length());
- buffer.put(_name.getBytes());
+ byteBuffer.put((byte)(0x40));
+ NBitIntegerEncoder.encode(byteBuffer, 5, _name.length());
+ byteBuffer.put(_name.getBytes());
}
if (_huffmanValue)
{
- buffer.put((byte)(0x80));
- NBitIntegerEncoder.encode(buffer, 7, HuffmanEncoder.octetsNeeded(_value));
- HuffmanEncoder.encode(buffer, _value);
+ byteBuffer.put((byte)(0x80));
+ NBitIntegerEncoder.encode(byteBuffer, 7, HuffmanEncoder.octetsNeeded(_value));
+ HuffmanEncoder.encode(byteBuffer, _value);
}
else
{
- buffer.put((byte)(0x00));
- NBitIntegerEncoder.encode(buffer, 5, _value.length());
- buffer.put(_value.getBytes());
+ byteBuffer.put((byte)(0x00));
+ NBitIntegerEncoder.encode(byteBuffer, 5, _value.length());
+ byteBuffer.put(_value.getBytes());
}
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SectionAcknowledgmentInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SectionAcknowledgmentInstruction.java
index 9cd0dba17f1..85cd979072d 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SectionAcknowledgmentInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SectionAcknowledgmentInstruction.java
@@ -15,17 +15,18 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class SectionAcknowledgmentInstruction implements Instruction
+public class SectionAcknowledgmentInstruction extends AbstractInstruction
{
private final long _streamId;
- public SectionAcknowledgmentInstruction(long streamId)
+ public SectionAcknowledgmentInstruction(RetainableByteBufferPool bufferPool, long streamId)
{
+ super(bufferPool);
_streamId = streamId;
}
@@ -35,14 +36,16 @@ public class SectionAcknowledgmentInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(7, _streamId) + 1;
- ByteBuffer buffer = lease.acquire(size, false);
- buffer.put((byte)0x80);
- NBitIntegerEncoder.encode(buffer, 7, _streamId);
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.put((byte)0x80);
+ NBitIntegerEncoder.encode(byteBuffer, 7, _streamId);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SetCapacityInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SetCapacityInstruction.java
index 68bc69d0f49..9582db62b87 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SetCapacityInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/SetCapacityInstruction.java
@@ -15,17 +15,18 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class SetCapacityInstruction implements Instruction
+public class SetCapacityInstruction extends AbstractInstruction
{
private final int _capacity;
- public SetCapacityInstruction(int capacity)
+ public SetCapacityInstruction(RetainableByteBufferPool bufferPool, int capacity)
{
+ super(bufferPool);
_capacity = capacity;
}
@@ -35,14 +36,16 @@ public class SetCapacityInstruction implements Instruction
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(5, _capacity) + 1;
- ByteBuffer buffer = lease.acquire(size, false);
- buffer.put((byte)0x20);
- NBitIntegerEncoder.encode(buffer, 5, _capacity);
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.put((byte)0x20);
+ NBitIntegerEncoder.encode(byteBuffer, 5, _capacity);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/StreamCancellationInstruction.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/StreamCancellationInstruction.java
index fc8ce46e0cd..ae3ad81b59e 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/StreamCancellationInstruction.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/main/java/org/eclipse/jetty/http3/qpack/internal/instruction/StreamCancellationInstruction.java
@@ -15,29 +15,32 @@ package org.eclipse.jetty.http3.qpack.internal.instruction;
import java.nio.ByteBuffer;
-import org.eclipse.jetty.http3.qpack.Instruction;
import org.eclipse.jetty.http3.qpack.internal.util.NBitIntegerEncoder;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBuffer;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-public class StreamCancellationInstruction implements Instruction
+public class StreamCancellationInstruction extends AbstractInstruction
{
private final long _streamId;
- public StreamCancellationInstruction(long streamId)
+ public StreamCancellationInstruction(RetainableByteBufferPool bufferPool, long streamId)
{
+ super(bufferPool);
_streamId = streamId;
}
@Override
- public void encode(ByteBufferPool.Lease lease)
+ public void encode(RetainableByteBufferPool.Accumulator accumulator)
{
int size = NBitIntegerEncoder.octetsNeeded(6, _streamId) + 1;
- ByteBuffer buffer = lease.acquire(size, false);
- buffer.put((byte)0x40);
- NBitIntegerEncoder.encode(buffer, 6, _streamId);
- BufferUtil.flipToFlush(buffer, 0);
- lease.append(buffer, true);
+ RetainableByteBuffer buffer = getRetainableByteBufferPool().acquire(size, false);
+ ByteBuffer byteBuffer = buffer.getByteBuffer();
+ BufferUtil.clearToFill(byteBuffer);
+ byteBuffer.put((byte)0x40);
+ NBitIntegerEncoder.encode(byteBuffer, 6, _streamId);
+ BufferUtil.flipToFlush(byteBuffer, 0);
+ accumulator.append(buffer);
}
@Override
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/BlockedStreamsTest.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/BlockedStreamsTest.java
index 2584c43d52a..c72e0a9621c 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/BlockedStreamsTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/BlockedStreamsTest.java
@@ -23,6 +23,8 @@ import org.eclipse.jetty.http3.qpack.internal.instruction.InsertCountIncrementIn
import org.eclipse.jetty.http3.qpack.internal.instruction.LiteralNameEntryInstruction;
import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentInstruction;
import org.eclipse.jetty.http3.qpack.internal.instruction.SetCapacityInstruction;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -54,8 +56,9 @@ public class BlockedStreamsTest
{
_encoderHandler = new TestEncoderHandler();
_decoderHandler = new TestDecoderHandler();
- _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS);
- _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ _encoder = new QpackEncoder(bufferPool, _encoderHandler, MAX_BLOCKED_STREAMS);
+ _decoder = new QpackDecoder(bufferPool, _decoderHandler, MAX_HEADER_SIZE);
}
@Test
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java
index 6e9de70b601..f2b8b6baf60 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EncodeDecodeTest.java
@@ -27,6 +27,8 @@ import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentI
import org.eclipse.jetty.http3.qpack.internal.instruction.SetCapacityInstruction;
import org.eclipse.jetty.http3.qpack.internal.parser.DecoderInstructionParser;
import org.eclipse.jetty.http3.qpack.internal.parser.EncoderInstructionParser;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
@@ -56,7 +58,8 @@ public class EncodeDecodeTest
{
_encoderHandler = new TestEncoderHandler();
_decoderHandler = new TestDecoderHandler();
- _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS)
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ _encoder = new QpackEncoder(bufferPool, _encoderHandler, MAX_BLOCKED_STREAMS)
{
@Override
protected boolean shouldHuffmanEncode(HttpField httpField)
@@ -64,7 +67,7 @@ public class EncodeDecodeTest
return false;
}
};
- _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE);
+ _decoder = new QpackDecoder(bufferPool, _decoderHandler, MAX_HEADER_SIZE);
_encoderInstructionParser = new EncoderInstructionParser(new EncoderParserDebugHandler(_encoder));
_decoderInstructionParser = new DecoderInstructionParser(new DecoderParserDebugHandler(_decoder));
@@ -91,7 +94,7 @@ public class EncodeDecodeTest
assertThat(_decoderHandler.getInstruction(), instanceOf(SectionAcknowledgmentInstruction.class));
assertTrue(_decoderHandler.isEmpty());
- _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new SectionAcknowledgmentInstruction(streamId))));
+ _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new SectionAcknowledgmentInstruction(_encoder.getRetainableByteBufferPool(), streamId))));
// B.2. Dynamic Table.
@@ -143,8 +146,8 @@ public class EncodeDecodeTest
assertTrue(_decoderHandler.isEmpty());
// Parse the decoder instructions on the encoder.
- _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new InsertCountIncrementInstruction(2))));
- _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new SectionAcknowledgmentInstruction(streamId))));
+ _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new InsertCountIncrementInstruction(_encoder.getRetainableByteBufferPool(), 2))));
+ _encoderInstructionParser.parse(QpackTestUtil.toBuffer(List.of(new SectionAcknowledgmentInstruction(_encoder.getRetainableByteBufferPool(), streamId))));
// B.3. Speculative Insert
_encoder.insert(new HttpField("custom-key", "custom-value"));
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EvictionTest.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EvictionTest.java
index d0e694bf1b6..a24b3664cc8 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EvictionTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/EvictionTest.java
@@ -20,6 +20,8 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -40,8 +42,9 @@ public class EvictionTest
@BeforeEach
public void before()
{
- _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE);
- _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS)
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ _decoder = new QpackDecoder(bufferPool, _decoderHandler, MAX_HEADER_SIZE);
+ _encoder = new QpackEncoder(bufferPool, _encoderHandler, MAX_BLOCKED_STREAMS)
{
@Override
protected boolean shouldHuffmanEncode(HttpField httpField)
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/InstructionGeneratorTest.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/InstructionGeneratorTest.java
index 03352c447b4..42eb19789ee 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/InstructionGeneratorTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/InstructionGeneratorTest.java
@@ -15,8 +15,8 @@ package org.eclipse.jetty.http3.qpack;
import org.eclipse.jetty.http3.qpack.internal.instruction.IndexedNameEntryInstruction;
import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentInstruction;
-import org.eclipse.jetty.io.ByteBufferPool;
-import org.eclipse.jetty.io.MappedByteBufferPool;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.Test;
@@ -26,14 +26,14 @@ import static org.hamcrest.Matchers.is;
public class InstructionGeneratorTest
{
- private final ByteBufferPool _bufferPool = new MappedByteBufferPool();
+ private final RetainableByteBufferPool _bufferPool = new ArrayRetainableByteBufferPool();
private String toHexString(Instruction instruction)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(_bufferPool);
- instruction.encode(lease);
- assertThat(lease.getSize(), is(1));
- return BufferUtil.toHexString(lease.getByteBuffers().get(0));
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ instruction.encode(accumulator);
+ assertThat(accumulator.getSize(), is(1));
+ return BufferUtil.toHexString(accumulator.getByteBuffers().get(0));
}
@Test
@@ -41,10 +41,10 @@ public class InstructionGeneratorTest
{
Instruction instruction;
- instruction = new SectionAcknowledgmentInstruction(4);
+ instruction = new SectionAcknowledgmentInstruction(_bufferPool, 4);
assertThat(toHexString(instruction), equalToIgnoringCase("84"));
- instruction = new SectionAcknowledgmentInstruction(1337);
+ instruction = new SectionAcknowledgmentInstruction(_bufferPool, 1337);
assertThat(toHexString(instruction), equalToIgnoringCase("FFBA09"));
}
@@ -53,10 +53,10 @@ public class InstructionGeneratorTest
{
Instruction instruction;
- instruction = new IndexedNameEntryInstruction(false, 0, false, "www.example.com");
+ instruction = new IndexedNameEntryInstruction(_bufferPool, false, 0, false, "www.example.com");
assertThat(toHexString(instruction), equalToIgnoringCase("c00f7777772e6578616d706c652e636f6d"));
- instruction = new IndexedNameEntryInstruction(false, 1, false, "/sample/path");
+ instruction = new IndexedNameEntryInstruction(_bufferPool, false, 1, false, "/sample/path");
assertThat(toHexString(instruction), equalToIgnoringCase("c10c2f73616d706c652f70617468"));
}
}
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java
index 5cacd32c972..4040d85cc62 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/QpackTestUtil.java
@@ -20,9 +20,9 @@ import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.http.MetaData;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.TypeUtil;
+import org.eclipse.jetty.util.StringUtil;
import org.hamcrest.Matcher;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -32,14 +32,14 @@ public class QpackTestUtil
{
public static ByteBuffer toBuffer(Instruction... instructions)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
for (Instruction instruction : instructions)
{
- instruction.encode(lease);
+ instruction.encode(accumulator);
}
- ByteBuffer combinedBuffer = BufferUtil.allocate(Math.toIntExact(lease.getTotalLength()));
+ ByteBuffer combinedBuffer = BufferUtil.allocate(Math.toIntExact(accumulator.getTotalLength()));
BufferUtil.clearToFill(combinedBuffer);
- for (ByteBuffer buffer : lease.getByteBuffers())
+ for (ByteBuffer buffer : accumulator.getByteBuffers())
{
combinedBuffer.put(buffer);
}
@@ -55,12 +55,12 @@ public class QpackTestUtil
public static ByteBuffer toBuffer(List instructions)
{
- ByteBufferPool.Lease lease = new ByteBufferPool.Lease(ByteBufferPool.NOOP);
- instructions.forEach(i -> i.encode(lease));
- assertThat(lease.getSize(), is(instructions.size()));
- ByteBuffer combinedBuffer = BufferUtil.allocate(Math.toIntExact(lease.getTotalLength()), false);
+ RetainableByteBufferPool.Accumulator accumulator = new RetainableByteBufferPool.Accumulator();
+ instructions.forEach(i -> i.encode(accumulator));
+ assertThat(accumulator.getSize(), is(instructions.size()));
+ ByteBuffer combinedBuffer = BufferUtil.allocate(Math.toIntExact(accumulator.getTotalLength()), false);
BufferUtil.clearToFill(combinedBuffer);
- lease.getByteBuffers().forEach(combinedBuffer::put);
+ accumulator.getByteBuffers().forEach(combinedBuffer::put);
BufferUtil.flipToFlush(combinedBuffer, 0);
return combinedBuffer;
}
@@ -68,7 +68,7 @@ public class QpackTestUtil
public static ByteBuffer hexToBuffer(String hexString)
{
hexString = hexString.replaceAll("\\s+", "");
- return ByteBuffer.wrap(TypeUtil.fromHexString(hexString));
+ return ByteBuffer.wrap(StringUtil.fromHexString(hexString));
}
public static String toHexString(Instruction instruction)
diff --git a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java
index bc2eda81ce6..f58d30a74e7 100644
--- a/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java
+++ b/jetty-core/jetty-http3/jetty-http3-qpack/src/test/java/org/eclipse/jetty/http3/qpack/SectionAcknowledgmentTest.java
@@ -17,6 +17,8 @@ import java.nio.ByteBuffer;
import org.eclipse.jetty.http3.qpack.QpackException.SessionException;
import org.eclipse.jetty.http3.qpack.internal.instruction.SectionAcknowledgmentInstruction;
+import org.eclipse.jetty.io.ArrayRetainableByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.util.BufferUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -46,8 +48,9 @@ public class SectionAcknowledgmentTest
{
_encoderHandler = new TestEncoderHandler();
_decoderHandler = new TestDecoderHandler();
- _encoder = new QpackEncoder(_encoderHandler, MAX_BLOCKED_STREAMS);
- _decoder = new QpackDecoder(_decoderHandler, MAX_HEADER_SIZE);
+ RetainableByteBufferPool bufferPool = new ArrayRetainableByteBufferPool();
+ _encoder = new QpackEncoder(bufferPool, _encoderHandler, MAX_BLOCKED_STREAMS);
+ _decoder = new QpackDecoder(bufferPool, _decoderHandler, MAX_HEADER_SIZE);
}
@Test
@@ -74,7 +77,7 @@ public class SectionAcknowledgmentTest
assertThat(BufferUtil.remaining(buffer), greaterThan(0L));
// Parsing a section ack instruction on the encoder when we are not expecting it should result in QPACK_DECODER_STREAM_ERROR.
- SectionAcknowledgmentInstruction instruction = new SectionAcknowledgmentInstruction(0);
+ SectionAcknowledgmentInstruction instruction = new SectionAcknowledgmentInstruction(_encoder.getRetainableByteBufferPool(), 0);
ByteBuffer instructionBuffer = toBuffer(instruction);
SessionException error = assertThrows(SessionException.class, () -> _encoder.parseInstructions(instructionBuffer));
assertThat(error.getErrorCode(), equalTo(QpackException.QPACK_ENCODER_STREAM_ERROR));
diff --git a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnector.java b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnector.java
index b8aa6230be2..dc83937ae02 100644
--- a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnector.java
+++ b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/HTTP3ServerConnector.java
@@ -18,7 +18,7 @@ import java.util.concurrent.Executor;
import org.eclipse.jetty.http.HttpField;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.PreEncodedHttpField;
-import org.eclipse.jetty.io.ByteBufferPool;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.server.QuicServerConnector;
import org.eclipse.jetty.server.ConnectionFactory;
import org.eclipse.jetty.server.Server;
@@ -44,7 +44,7 @@ public class HTTP3ServerConnector extends QuicServerConnector
this(server, null, null, null, sslContextFactory, factories);
}
- public HTTP3ServerConnector(Server server, Executor executor, Scheduler scheduler, ByteBufferPool bufferPool, SslContextFactory.Server sslContextFactory, ConnectionFactory... factories)
+ public HTTP3ServerConnector(Server server, Executor executor, Scheduler scheduler, RetainableByteBufferPool bufferPool, SslContextFactory.Server sslContextFactory, ConnectionFactory... factories)
{
super(server, executor, scheduler, bufferPool, sslContextFactory, factories);
// Max concurrent streams that a client can open.
diff --git a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3Session.java b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3Session.java
index adcf58e44d4..8003b737acd 100644
--- a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3Session.java
+++ b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3Session.java
@@ -30,6 +30,7 @@ import org.eclipse.jetty.http3.internal.MessageFlusher;
import org.eclipse.jetty.http3.internal.UnidirectionalStreamConnection;
import org.eclipse.jetty.http3.qpack.QpackDecoder;
import org.eclipse.jetty.http3.qpack.QpackEncoder;
+import org.eclipse.jetty.io.RetainableByteBufferPool;
import org.eclipse.jetty.quic.common.QuicStreamEndPoint;
import org.eclipse.jetty.quic.common.StreamType;
import org.eclipse.jetty.quic.server.ServerProtocolSession;
@@ -62,7 +63,8 @@ public class ServerHTTP3Session extends ServerProtocolSession
long encoderStreamId = getQuicSession().newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
QuicStreamEndPoint encoderEndPoint = openInstructionEndPoint(encoderStreamId);
InstructionFlusher encoderInstructionFlusher = new InstructionFlusher(quicSession, encoderEndPoint, EncoderStreamConnection.STREAM_TYPE);
- this.encoder = new QpackEncoder(new InstructionHandler(encoderInstructionFlusher), configuration.getMaxBlockedStreams());
+ RetainableByteBufferPool bufferPool = quicSession.getRetainableByteBufferPool();
+ this.encoder = new QpackEncoder(bufferPool, new InstructionHandler(encoderInstructionFlusher), configuration.getMaxBlockedStreams());
addBean(encoder);
if (LOG.isDebugEnabled())
LOG.debug("created encoder stream #{} on {}", encoderStreamId, encoderEndPoint);
@@ -70,7 +72,7 @@ public class ServerHTTP3Session extends ServerProtocolSession
long decoderStreamId = getQuicSession().newStreamId(StreamType.SERVER_UNIDIRECTIONAL);
QuicStreamEndPoint decoderEndPoint = openInstructionEndPoint(decoderStreamId);
InstructionFlusher decoderInstructionFlusher = new InstructionFlusher(quicSession, decoderEndPoint, DecoderStreamConnection.STREAM_TYPE);
- this.decoder = new QpackDecoder(new InstructionHandler(decoderInstructionFlusher), configuration.getMaxRequestHeadersSize());
+ this.decoder = new QpackDecoder(bufferPool, new InstructionHandler(decoderInstructionFlusher), configuration.getMaxRequestHeadersSize());
addBean(decoder);
if (LOG.isDebugEnabled())
LOG.debug("created decoder stream #{} on {}", decoderStreamId, decoderEndPoint);
@@ -82,7 +84,7 @@ public class ServerHTTP3Session extends ServerProtocolSession
if (LOG.isDebugEnabled())
LOG.debug("created control stream #{} on {}", controlStreamId, controlEndPoint);
- this.messageFlusher = new MessageFlusher(quicSession.getByteBufferPool(), encoder, configuration.getMaxResponseHeadersSize(), configuration.isUseOutputDirectByteBuffers());
+ this.messageFlusher = new MessageFlusher(quicSession.getRetainableByteBufferPool(), encoder, configuration.getMaxResponseHeadersSize(), configuration.isUseOutputDirectByteBuffers());
addBean(messageFlusher);
}
@@ -189,7 +191,7 @@ public class ServerHTTP3Session extends ServerProtocolSession
private void openUnidirectionalStreamEndPoint(QuicStreamEndPoint endPoint)
{
- UnidirectionalStreamConnection connection = new UnidirectionalStreamConnection(endPoint, getQuicSession().getExecutor(), getQuicSession().getByteBufferPool(), encoder, decoder, session);
+ UnidirectionalStreamConnection connection = new UnidirectionalStreamConnection(endPoint, getQuicSession().getExecutor(), getQuicSession().getRetainableByteBufferPool(), encoder, decoder, session);
endPoint.setConnection(connection);
endPoint.opened();
}
diff --git a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
index 01d08089491..0539977f962 100644
--- a/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
+++ b/jetty-core/jetty-http3/jetty-http3-server/src/main/java/org/eclipse/jetty/http3/server/internal/ServerHTTP3StreamConnection.java
@@ -42,7 +42,7 @@ public class ServerHTTP3StreamConnection extends HTTP3StreamConnection implement
public ServerHTTP3StreamConnection(Connector connector, HttpConfiguration httpConfiguration, QuicStreamEndPoint endPoint, ServerHTTP3Session session, MessageParser parser)
{
- super(endPoint, connector.getExecutor(), connector.getByteBufferPool(), parser);
+ super(endPoint, connector.getExecutor(), connector.getRetainableByteBufferPool(), parser);
this.connector = connector;
this.httpConfiguration = httpConfiguration;
this.session = session;
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
deleted file mode 100644
index 748ec94a3a3..00000000000
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractByteBufferPool.java
+++ /dev/null
@@ -1,276 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.io;
-
-import java.nio.ByteBuffer;
-import java.util.Objects;
-import java.util.Queue;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.function.Consumer;
-import java.util.function.IntConsumer;
-
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.NanoTime;
-import org.eclipse.jetty.util.annotation.ManagedAttribute;
-import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.annotation.ManagedOperation;
-
-/**
- * The {@code maxHeapMemory} and {@code maxDirectMemory} default heuristic is to use {@link Runtime#maxMemory()}
- * divided by 4.
- */
-@ManagedObject
-abstract class AbstractByteBufferPool implements ByteBufferPool
-{
- public static final int DEFAULT_FACTOR = 4096;
- public static final int DEFAULT_MAX_CAPACITY_BY_FACTOR = 16;
- private final int _factor;
- private final int _maxCapacity;
- private final int _maxBucketSize;
- private final long _maxHeapMemory;
- private final long _maxDirectMemory;
- private final AtomicLong _heapMemory = new AtomicLong();
- private final AtomicLong _directMemory = new AtomicLong();
- private final RetainableByteBufferPool _retainableByteBufferPool;
-
- /**
- * Creates a new ByteBufferPool with the given configuration.
- *
- * @param factor the capacity factor
- * @param maxBucketSize the maximum ByteBuffer queue length
- * @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
- * @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
- */
- protected AbstractByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
- {
- _factor = factor <= 0 ? DEFAULT_FACTOR : factor;
- _maxCapacity = maxCapacity > 0 ? maxCapacity : DEFAULT_MAX_CAPACITY_BY_FACTOR * _factor;
- _maxBucketSize = maxBucketSize;
- _maxHeapMemory = memorySize(maxHeapMemory);
- _maxDirectMemory = memorySize(maxDirectMemory);
- _retainableByteBufferPool = (retainedHeapMemory == -2 && retainedDirectMemory == -2)
- ? RetainableByteBufferPool.from(this)
- : newRetainableByteBufferPool(factor, maxCapacity, maxBucketSize, retainedSize(retainedHeapMemory), retainedSize(retainedDirectMemory));
- }
-
- static long retainedSize(long size)
- {
- if (size == -2)
- return 0;
- return memorySize(size);
- }
-
- static long memorySize(long size)
- {
- if (size < 0)
- return -1;
- if (size == 0)
- return Runtime.getRuntime().maxMemory() / 4;
- return size;
- }
-
- protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
- {
- return RetainableByteBufferPool.from(this);
- }
-
- @Override
- public RetainableByteBufferPool asRetainableByteBufferPool()
- {
- return _retainableByteBufferPool;
- }
-
- protected int getCapacityFactor()
- {
- return _factor;
- }
-
- protected int getMaxCapacity()
- {
- return _maxCapacity;
- }
-
- protected int getMaxBucketSize()
- {
- return _maxBucketSize;
- }
-
- @Deprecated
- protected void decrementMemory(ByteBuffer buffer)
- {
- updateMemory(buffer, false);
- }
-
- @Deprecated
- protected void incrementMemory(ByteBuffer buffer)
- {
- updateMemory(buffer, true);
- }
-
- private void updateMemory(ByteBuffer buffer, boolean addOrSub)
- {
- AtomicLong memory = buffer.isDirect() ? _directMemory : _heapMemory;
- int capacity = buffer.capacity();
- memory.addAndGet(addOrSub ? capacity : -capacity);
- }
-
- protected void releaseExcessMemory(boolean direct, Consumer clearFn)
- {
- long maxMemory = direct ? _maxDirectMemory : _maxHeapMemory;
- if (maxMemory > 0)
- {
- while (getMemory(direct) > maxMemory)
- {
- clearFn.accept(direct);
- }
- }
- }
-
- @ManagedAttribute("The bytes retained by direct ByteBuffers")
- public long getDirectMemory()
- {
- return getMemory(true);
- }
-
- @ManagedAttribute("The bytes retained by heap ByteBuffers")
- public long getHeapMemory()
- {
- return getMemory(false);
- }
-
- @ManagedAttribute("The max num of bytes that can be retained from direct ByteBuffers")
- public long getMaxDirectMemory()
- {
- return _maxDirectMemory;
- }
-
- @ManagedAttribute("The max num of bytes that can be retained from heap ByteBuffers")
- public long getMaxHeapMemory()
- {
- return _maxHeapMemory;
- }
-
- public long getMemory(boolean direct)
- {
- AtomicLong memory = direct ? _directMemory : _heapMemory;
- return memory.get();
- }
-
- protected static class Bucket
- {
- private final Queue _queue = new ConcurrentLinkedQueue<>();
- private final int _capacity;
- private final int _maxSize;
- private final AtomicInteger _size;
- private final AtomicLong _lastUpdate = new AtomicLong(NanoTime.now());
- private final IntConsumer _memoryFunction;
-
- @Deprecated
- public Bucket(int capacity, int maxSize)
- {
- this(capacity, maxSize, i -> {});
- }
-
- public Bucket(int capacity, int maxSize, IntConsumer memoryFunction)
- {
- _capacity = capacity;
- _maxSize = maxSize;
- _size = maxSize > 0 ? new AtomicInteger() : null;
- _memoryFunction = Objects.requireNonNull(memoryFunction);
- }
-
- public ByteBuffer acquire()
- {
- ByteBuffer buffer = _queue.poll();
- if (buffer != null)
- {
- if (_size != null)
- _size.decrementAndGet();
- _memoryFunction.accept(-buffer.capacity());
- }
-
- return buffer;
- }
-
- public void release(ByteBuffer buffer)
- {
- resetUpdateTime();
- BufferUtil.reset(buffer);
- if (_size == null || _size.incrementAndGet() <= _maxSize)
- {
- _queue.offer(buffer);
- _memoryFunction.accept(buffer.capacity());
- }
- else
- {
- _size.decrementAndGet();
- }
- }
-
- void resetUpdateTime()
- {
- _lastUpdate.lazySet(NanoTime.now());
- }
-
- public void clear()
- {
- int size = _size == null ? 0 : _size.get() - 1;
- while (size >= 0)
- {
- ByteBuffer buffer = acquire();
- if (buffer == null)
- break;
- if (_size != null)
- --size;
- }
- }
-
- boolean isEmpty()
- {
- return _queue.isEmpty();
- }
-
- int size()
- {
- return _queue.size();
- }
-
- long getLastUpdate()
- {
- return _lastUpdate.getOpaque();
- }
-
- @Override
- public String toString()
- {
- return String.format("%s@%x{capacity=%d, size=%d, maxSize=%d}", getClass().getSimpleName(), hashCode(), _capacity, size(), _maxSize);
- }
- }
-
- IntConsumer updateMemory(boolean direct)
- {
- return (direct) ? _directMemory::addAndGet : _heapMemory::addAndGet;
- }
-
- @ManagedOperation(value = "Clears this ByteBufferPool", impact = "ACTION")
- public void clear()
- {
- _heapMemory.set(0);
- _directMemory.set(0);
- }
-}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractRetainableByteBuffer.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractRetainableByteBuffer.java
new file mode 100644
index 00000000000..1c1a859a3c2
--- /dev/null
+++ b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/AbstractRetainableByteBuffer.java
@@ -0,0 +1,78 @@
+//
+// ========================================================================
+// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
+//
+// This program and the accompanying materials are made available under the
+// terms of the Eclipse Public License v. 2.0 which is available at
+// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+// which is available at https://www.apache.org/licenses/LICENSE-2.0.
+//
+// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+// ========================================================================
+//
+
+package org.eclipse.jetty.io;
+
+import java.nio.ByteBuffer;
+import java.util.Objects;
+
+import org.eclipse.jetty.util.BufferUtil;
+
+/**
+ *
Abstract implementation of {@link RetainableByteBuffer} with
+ * reference counting.
+ */
+public abstract class AbstractRetainableByteBuffer implements RetainableByteBuffer
+{
+ private final ReferenceCounter refCount = new ReferenceCounter(0);
+ private final ByteBuffer byteBuffer;
+
+ public AbstractRetainableByteBuffer(ByteBuffer byteBuffer)
+ {
+ this.byteBuffer = Objects.requireNonNull(byteBuffer);
+ }
+
+ /**
+ * @see ReferenceCounter#acquire()
+ */
+ protected void acquire()
+ {
+ refCount.acquire();
+ }
+
+ @Override
+ public boolean canRetain()
+ {
+ return refCount.canRetain();
+ }
+
+ @Override
+ public void retain()
+ {
+ refCount.retain();
+ }
+
+ @Override
+ public boolean release()
+ {
+ return refCount.release();
+ }
+
+ @Override
+ public boolean isRetained()
+ {
+ return refCount.isRetained();
+ }
+
+ @Override
+ public ByteBuffer getByteBuffer()
+ {
+ return byteBuffer;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "%s@%x[r=%d,%s]".formatted(getClass().getSimpleName(), hashCode(), refCount.get(), BufferUtil.toDetailString(byteBuffer));
+ }
+}
diff --git a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java b/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
deleted file mode 100644
index 57600ea4514..00000000000
--- a/jetty-core/jetty-io/src/main/java/org/eclipse/jetty/io/ArrayByteBufferPool.java
+++ /dev/null
@@ -1,342 +0,0 @@
-//
-// ========================================================================
-// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
-//
-// This program and the accompanying materials are made available under the
-// terms of the Eclipse Public License v. 2.0 which is available at
-// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
-// which is available at https://www.apache.org/licenses/LICENSE-2.0.
-//
-// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
-// ========================================================================
-//
-
-package org.eclipse.jetty.io;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-import org.eclipse.jetty.util.BufferUtil;
-import org.eclipse.jetty.util.NanoTime;
-import org.eclipse.jetty.util.annotation.ManagedAttribute;
-import org.eclipse.jetty.util.annotation.ManagedObject;
-import org.eclipse.jetty.util.component.Dumpable;
-import org.eclipse.jetty.util.component.DumpableCollection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
A ByteBuffer pool where ByteBuffers are held in queues that are held in array elements.
- *
Given a capacity {@code factor} of 4096, the first array element holds a bucket of ByteBuffers
- * each of capacity 4096, the second array element holds a bucket of ByteBuffers each of capacity
- * 8192, and so on.
- *
The {@code maxHeapMemory} and {@code maxDirectMemory} default heuristic is to use {@link Runtime#maxMemory()}
- * divided by 4.
- */
-@ManagedObject
-public class ArrayByteBufferPool extends AbstractByteBufferPool implements Dumpable
-{
- private static final Logger LOG = LoggerFactory.getLogger(ArrayByteBufferPool.class);
-
- private final int _maxCapacity;
- private final int _minCapacity;
- private final Bucket[] _direct;
- private final Bucket[] _indirect;
- private boolean _detailedDump = false;
-
- /**
- * Creates a new ArrayByteBufferPool with a default configuration.
- * Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
- */
- public ArrayByteBufferPool()
- {
- this(-1, -1, -1);
- }
-
- /**
- * Creates a new ArrayByteBufferPool with the given configuration.
- * Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
- *
- * @param minCapacity the minimum ByteBuffer capacity
- * @param factor the capacity factor
- * @param maxCapacity the maximum ByteBuffer capacity
- */
- public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity)
- {
- this(minCapacity, factor, maxCapacity, -1, 0, 0);
- }
-
- /**
- * Creates a new ArrayByteBufferPool with the given configuration.
- * Both {@code maxHeapMemory} and {@code maxDirectMemory} default to 0 to use default heuristic.
- *
- * @param minCapacity the minimum ByteBuffer capacity
- * @param factor the capacity factor
- * @param maxCapacity the maximum ByteBuffer capacity
- * @param maxQueueLength the maximum ByteBuffer queue length
- */
- public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxQueueLength)
- {
- this(minCapacity, factor, maxCapacity, maxQueueLength, 0, 0);
- }
-
- /**
- * Creates a new ArrayByteBufferPool with the given configuration.
- *
- * @param minCapacity the minimum ByteBuffer capacity
- * @param factor the capacity factor
- * @param maxCapacity the maximum ByteBuffer capacity
- * @param maxBucketSize the maximum ByteBuffer queue length in a {@link Bucket}
- * @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- */
- public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory)
- {
- this(minCapacity, factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, maxHeapMemory, maxDirectMemory);
- }
-
- /**
- * Creates a new ArrayByteBufferPool with the given configuration.
- *
- * @param minCapacity the minimum ByteBuffer capacity
- * @param factor the capacity factor
- * @param maxCapacity the maximum ByteBuffer capacity
- * @param maxBucketSize the maximum ByteBuffer queue length in a {@link Bucket}
- * @param maxHeapMemory the max heap memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param maxDirectMemory the max direct memory in bytes, -1 for unlimited memory or 0 to use default heuristic
- * @param retainedHeapMemory the max heap memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
- * @param retainedDirectMemory the max direct memory in bytes, -2 for no retained memory, -1 for unlimited retained memory or 0 to use default heuristic
- */
- public ArrayByteBufferPool(int minCapacity, int factor, int maxCapacity, int maxBucketSize, long maxHeapMemory, long maxDirectMemory, long retainedHeapMemory, long retainedDirectMemory)
- {
- super(factor, maxCapacity, maxBucketSize, maxHeapMemory, maxDirectMemory, retainedHeapMemory, retainedDirectMemory);
- maxCapacity = getMaxCapacity();
-
- factor = getCapacityFactor();
- if (minCapacity <= 0)
- minCapacity = 0;
- if ((maxCapacity % factor) != 0 || factor >= maxCapacity)
- throw new IllegalArgumentException("The capacity factor must be a divisor of maxCapacity");
- _maxCapacity = maxCapacity;
- _minCapacity = minCapacity;
-
- // Initialize all buckets in constructor and never modify the array again.
- int length = bucketFor(maxCapacity) + 1;
- _direct = new Bucket[length];
- _indirect = new Bucket[length];
- for (int i = 0; i < length; i++)
- {
- _direct[i] = newBucket(i, true);
- _indirect[i] = newBucket(i, false);
- }
- }
-
- @Override
- protected RetainableByteBufferPool newRetainableByteBufferPool(int factor, int maxCapacity, int maxBucketSize, long retainedHeapMemory, long retainedDirectMemory)
- {
- return new Retained(factor, maxCapacity, maxBucketSize, retainedHeapMemory, retainedDirectMemory);
- }
-
- @Override
- public ByteBuffer acquire(int size, boolean direct)
- {
- int capacity = size < _minCapacity ? size : capacityFor(bucketFor(size));
- Bucket bucket = bucketFor(size, direct);
- if (bucket == null)
- return newByteBuffer(capacity, direct);
- ByteBuffer buffer = bucket.acquire();
- if (buffer == null)
- return newByteBuffer(capacity, direct);
- return buffer;
- }
-
- @Override
- public void release(ByteBuffer buffer)
- {
- if (buffer == null)
- return;
-
- int capacity = buffer.capacity();
- // Validate that this buffer is from this pool.
- if (capacity != capacityFor(bucketFor(capacity)))
- {
- if (LOG.isDebugEnabled())
- LOG.debug("ByteBuffer {} does not belong to this pool, discarding it", BufferUtil.toDetailString(buffer));
- return;
- }
-
- // Don't release into the pool if greater than the maximum ByteBuffer capacity.
- if (capacity > _maxCapacity)
- return;
-
- boolean direct = buffer.isDirect();
- Bucket bucket = bucketFor(capacity, direct);
- if (bucket != null)
- {
- bucket.release(buffer);
- releaseExcessMemory(direct, this::releaseMemory);
- }
- }
-
- private Bucket newBucket(int key, boolean direct)
- {
- return new Bucket(capacityFor(key), getMaxBucketSize(), updateMemory(direct));
- }
-
- @Override
- public void clear()
- {
- super.clear();
- for (int i = 0; i < _direct.length; ++i)
- {
- _direct[i].clear();
- _indirect[i].clear();
- }
- }
-
- protected void releaseMemory(boolean direct)
- {
- long oldest = Long.MAX_VALUE;
- int index = -1;
- Bucket[] buckets = bucketsFor(direct);
- for (int i = 0; i < buckets.length; ++i)
- {
- Bucket bucket = buckets[i];
- if (bucket.isEmpty())
- continue;
- long lastUpdateNanoTime = bucket.getLastUpdate();
- if (oldest == Long.MAX_VALUE || NanoTime.isBefore(lastUpdateNanoTime, oldest))
- {
- oldest = lastUpdateNanoTime;
- index = i;
- }
- }
- if (index >= 0)
- {
- Bucket bucket = buckets[index];
- bucket.clear();
- }
- }
-
- protected int bucketFor(int capacity)
- {
- return (int)Math.ceil((double)capacity / getCapacityFactor());
- }
-
- protected int capacityFor(int bucket)
- {
- return bucket * getCapacityFactor();
- }
-
- protected Bucket bucketFor(int capacity, boolean direct)
- {
- if (capacity < _minCapacity)
- return null;
- int bucket = bucketFor(capacity);
- if (bucket >= _direct.length)
- return null;
- Bucket[] buckets = bucketsFor(direct);
- return buckets[bucket];
- }
-
- @ManagedAttribute("The number of pooled direct ByteBuffers")
- public long getDirectByteBufferCount()
- {
- return getByteBufferCount(true);
- }
-
- @ManagedAttribute("The number of pooled heap ByteBuffers")
- public long getHeapByteBufferCount()
- {
- return getByteBufferCount(false);
- }
-
- private long getByteBufferCount(boolean direct)
- {
- return Arrays.stream(bucketsFor(direct))
- .filter(Objects::nonNull)
- .mapToLong(Bucket::size)
- .sum();
- }
-
- // Package local for testing
- Bucket[] bucketsFor(boolean direct)
- {
- return direct ? _direct : _indirect;
- }
-
- public boolean isDetailedDump()
- {
- return _detailedDump;
- }
-
- public void setDetailedDump(boolean detailedDump)
- {
- _detailedDump = detailedDump;
- }
-
- @Override
- public void dump(Appendable out, String indent) throws IOException
- {
- List