mirror of
https://github.com/jetty/jetty.project.git
synced 2025-03-01 03:19:13 +00:00
Rejecting BufferPool.release() of buffers below factor
This commit is contained in:
parent
9a71d75003
commit
3fd59fa189
@ -25,9 +25,12 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
public class MappedByteBufferPool implements ByteBufferPool
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(MappedByteBufferPool.class);
|
||||
private final ConcurrentMap<Integer, Queue<ByteBuffer>> directBuffers = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Integer, Queue<ByteBuffer>> heapBuffers = new ConcurrentHashMap<>();
|
||||
private final int factor;
|
||||
@ -60,14 +63,24 @@ public class MappedByteBufferPool implements ByteBufferPool
|
||||
}
|
||||
|
||||
BufferUtil.clear(result);
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug("acquire({}, {}) -> {}", size, direct, BufferUtil.toDetailString(result));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release(ByteBuffer buffer)
|
||||
{
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.debug("release({})", BufferUtil.toDetailString(buffer));
|
||||
}
|
||||
|
||||
if (buffer == null)
|
||||
return;
|
||||
return; // nothing to do
|
||||
|
||||
if (buffer.capacity() < factor)
|
||||
return; // don't bother keeping track of this buffer (it obviously didn't come from this bytebuffer pool
|
||||
|
||||
int bucket = bucketFor(buffer.capacity());
|
||||
ConcurrentMap<Integer, Queue<ByteBuffer>> buffers = buffersFor(buffer.isDirect());
|
||||
|
@ -18,18 +18,17 @@
|
||||
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class MappedByteBufferPoolTest
|
||||
{
|
||||
@Test
|
||||
@ -82,4 +81,25 @@ public class MappedByteBufferPoolTest
|
||||
|
||||
assertTrue(buffers.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* In a scenario where BufferPool is being used, but some edges cases that use ByteBuffer.allocate()
|
||||
* and then later that buffer is released via the BufferPool, that non acquired buffer can contaminate
|
||||
* the buffer pool.
|
||||
*/
|
||||
@Test
|
||||
public void testReleaseTiny() throws Exception
|
||||
{
|
||||
MappedByteBufferPool bufferPool = new MappedByteBufferPool();
|
||||
|
||||
// Release a few small non-pool buffers
|
||||
bufferPool.release(ByteBuffer.wrap(StringUtil.getUtf8Bytes("Hello")));
|
||||
bufferPool.release(ByteBuffer.wrap(StringUtil.getUtf8Bytes("There")));
|
||||
|
||||
// acquire small pool
|
||||
ByteBuffer small = bufferPool.acquire(35, false);
|
||||
assertThat(small.capacity(), greaterThanOrEqualTo(35));
|
||||
small.limit(35);
|
||||
bufferPool.release(small);
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,2 @@
|
||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||
org.eclipse.jetty.LEVEL=INFO
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user