mirror of
https://github.com/jetty/jetty.project.git
synced 2025-02-28 10:59:19 +00:00
280843 buffer pool mixing types
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@492 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
e8862a3fb1
commit
f13ac17713
@ -3,6 +3,7 @@ jetty-7.0.0.RC0-SNAPSHOT
|
||||
+ JETTY-967 create standalone build for PKCS12Import at codehaus
|
||||
+ JETTY-1056 update jetty-ant module for Jetty 7 at codehaus trunk
|
||||
+ JETTY-1058 Handle trailing / with aliases
|
||||
+ 280843 Buffer pool uses isHeader
|
||||
|
||||
jetty-7.0.0.M4 1 June 2009
|
||||
+ 281059 NPE in QTP with debug on
|
||||
|
@ -379,7 +379,6 @@ public class HttpClient extends HttpBuffers implements Attributes
|
||||
/**
|
||||
* @see org.eclipse.jetty.http.HttpBuffers#newResponseHeader(int)
|
||||
*/
|
||||
@Override
|
||||
protected Buffer newResponseHeader(int size)
|
||||
{
|
||||
if (_connectorType == CONNECTOR_SOCKET)
|
||||
@ -387,6 +386,23 @@ public class HttpClient extends HttpBuffers implements Attributes
|
||||
return new IndirectNIOBuffer(size);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isRequestHeader(Buffer buffer)
|
||||
{
|
||||
if (_connectorType == CONNECTOR_SOCKET)
|
||||
return buffer instanceof ByteArrayBuffer;
|
||||
return buffer instanceof IndirectNIOBuffer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isResponseHeader(Buffer buffer)
|
||||
{
|
||||
if (_connectorType == CONNECTOR_SOCKET)
|
||||
return buffer instanceof ByteArrayBuffer;
|
||||
return buffer instanceof IndirectNIOBuffer;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public int getMaxConnectionsPerAddress()
|
||||
{
|
||||
|
@ -95,6 +95,11 @@ class SelectConnector extends AbstractLifeCycle implements HttpClient.Connector,
|
||||
// TODO indirect?
|
||||
return new DirectNIOBuffer(size);
|
||||
}
|
||||
@Override
|
||||
protected boolean isHeader(Buffer buffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
buffers.setBufferSize(ssl_session.getApplicationBufferSize());
|
||||
buffers.setHeaderSize(ssl_session.getPacketBufferSize());
|
||||
|
@ -39,6 +39,11 @@ public abstract class HttpBuffers extends AbstractLifeCycle
|
||||
{
|
||||
return newRequestHeader(size);
|
||||
}
|
||||
@Override
|
||||
protected boolean isHeader(Buffer buffer)
|
||||
{
|
||||
return isRequestHeader(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
private final ThreadLocalBuffers _responseBuffers = new ThreadLocalBuffers()
|
||||
@ -54,6 +59,11 @@ public abstract class HttpBuffers extends AbstractLifeCycle
|
||||
{
|
||||
return newResponseHeader(size);
|
||||
}
|
||||
@Override
|
||||
protected boolean isHeader(Buffer buffer)
|
||||
{
|
||||
return isResponseHeader(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
public HttpBuffers()
|
||||
@ -129,6 +139,22 @@ public abstract class HttpBuffers extends AbstractLifeCycle
|
||||
protected abstract Buffer newResponseBuffer(int size);
|
||||
|
||||
protected abstract Buffer newResponseHeader(int size);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param buffer
|
||||
* @return True if the buffer is the correct type for a request header buffer
|
||||
*/
|
||||
protected abstract boolean isRequestHeader(Buffer buffer);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param buffer
|
||||
* @return True if the buffer is the correct type for a response header buffer
|
||||
*/
|
||||
protected abstract boolean isResponseHeader(Buffer buffer);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param headerBufferSize The headerBufferSize to set.
|
||||
|
@ -24,7 +24,8 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
{
|
||||
private int _bufferSize=12*1024;
|
||||
private int _headerSize=6*1024;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private final ThreadLocal<ThreadBuffers> _buffers=new ThreadLocal<ThreadBuffers>()
|
||||
{
|
||||
protected ThreadBuffers initialValue()
|
||||
@ -33,6 +34,12 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public ThreadLocalBuffers()
|
||||
{
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getBuffer()
|
||||
{
|
||||
ThreadBuffers buffers = _buffers.get();
|
||||
@ -53,6 +60,7 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
return newBuffer(_bufferSize);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getHeader()
|
||||
{
|
||||
ThreadBuffers buffers = _buffers.get();
|
||||
@ -63,7 +71,7 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
return b;
|
||||
}
|
||||
|
||||
if (buffers._other!=null && buffers._other.capacity()==_headerSize)
|
||||
if (buffers._other!=null && buffers._other.capacity()==_headerSize && isHeader(buffers._other))
|
||||
{
|
||||
Buffer b=buffers._other;
|
||||
buffers._other=null;
|
||||
@ -73,6 +81,7 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
return newHeader(_headerSize);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public Buffer getBuffer(int size)
|
||||
{
|
||||
ThreadBuffers buffers = _buffers.get();
|
||||
@ -86,6 +95,7 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
return newBuffer(size);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
public void returnBuffer(Buffer buffer)
|
||||
{
|
||||
buffer.clear();
|
||||
@ -96,22 +106,17 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
|
||||
ThreadBuffers buffers = _buffers.get();
|
||||
|
||||
if (size==_bufferSize && buffers._buffer==null)
|
||||
{
|
||||
buffers._buffer=buffer;
|
||||
}
|
||||
else if (size==_headerSize && buffers._header==null)
|
||||
{
|
||||
if (buffers._header==null && size==_headerSize && isHeader(buffer))
|
||||
buffers._header=buffer;
|
||||
}
|
||||
else if (size==_bufferSize && buffers._buffer==null)
|
||||
buffers._buffer=buffer;
|
||||
else
|
||||
{
|
||||
buffers._other=buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the buffer size in bytes.
|
||||
*/
|
||||
@ -119,7 +124,8 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
{
|
||||
return _bufferSize;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return Returns the header size in bytes.
|
||||
*/
|
||||
@ -128,10 +134,30 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
return _headerSize;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Create a new content Buffer
|
||||
* @param size
|
||||
* @return new Buffer
|
||||
*/
|
||||
protected abstract Buffer newBuffer(int size);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* Create a new header Buffer
|
||||
* @param size
|
||||
* @return new Buffer
|
||||
*/
|
||||
protected abstract Buffer newHeader(int size);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param buffer
|
||||
* @return True if the buffer is the correct type to be a Header buffer
|
||||
*/
|
||||
protected abstract boolean isHeader(Buffer buffer);
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param size The buffer size in bytes
|
||||
*/
|
||||
@ -140,6 +166,7 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
_bufferSize = size;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @param size The header size in bytes
|
||||
*/
|
||||
@ -147,7 +174,9 @@ public abstract class ThreadLocalBuffers implements Buffers
|
||||
{
|
||||
_headerSize = size;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/* ------------------------------------------------------------ */
|
||||
protected static class ThreadBuffers
|
||||
{
|
||||
Buffer _buffer;
|
||||
|
@ -14,8 +14,10 @@
|
||||
package org.eclipse.jetty.io;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
@ -103,10 +105,126 @@ public class ThreadLocalBuffersTest
|
||||
throws Exception
|
||||
{
|
||||
execAbstractBuffer( );
|
||||
|
||||
}
|
||||
|
||||
public void testDifferentSizes()
|
||||
throws Exception
|
||||
{
|
||||
InnerBuffers buffers = new InnerBuffers();
|
||||
buffers.setHeaderSize(128);
|
||||
buffers.setBufferSize(256);
|
||||
|
||||
Buffer h1 = buffers.getHeader();
|
||||
Buffer h2 = buffers.getHeader();
|
||||
Buffer b1 = buffers.getBuffer();
|
||||
Buffer b2 = buffers.getBuffer();
|
||||
Buffer b3 = buffers.getBuffer(512);
|
||||
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(h2);
|
||||
buffers.returnBuffer(b1);
|
||||
buffers.returnBuffer(b2);
|
||||
buffers.returnBuffer(b3);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
assertTrue(h2!=buffers.getHeader()); // b2 replaced h2 in other slot
|
||||
assertTrue(b1==buffers.getBuffer()); // pooled buffer
|
||||
assertTrue(b2!=buffers.getBuffer()); // b3 replaced b2 in other slot
|
||||
assertTrue(b3==buffers.getBuffer(512)); // b2 from other slot
|
||||
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(h2);
|
||||
buffers.returnBuffer(b1);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
assertTrue(h2==buffers.getHeader()); // h2 in other slot
|
||||
assertTrue(b1==buffers.getBuffer()); // pooled buffer
|
||||
assertTrue(b2!=buffers.getBuffer()); // new buffer
|
||||
assertTrue(b3!=buffers.getBuffer(512)); // new buffer
|
||||
|
||||
|
||||
// check that sizes are respected
|
||||
buffers.returnBuffer(b3);
|
||||
buffers.returnBuffer(b1);
|
||||
buffers.returnBuffer(b2);
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(h2);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
assertTrue(h2==buffers.getHeader()); // h2 in other slot
|
||||
assertTrue(b1==buffers.getBuffer()); // pooled buffer
|
||||
assertTrue(b2!=buffers.getBuffer()); // new buffer
|
||||
assertTrue(b3!=buffers.getBuffer(512)); // new buffer
|
||||
}
|
||||
|
||||
public void testSameSizes()
|
||||
throws Exception
|
||||
{
|
||||
Buffer buffer=null;
|
||||
InnerBuffers buffers = new InnerBuffers();
|
||||
buffers.setHeaderSize(128);
|
||||
buffers.setBufferSize(128);
|
||||
|
||||
Buffer h1 = buffers.getHeader();
|
||||
Buffer h2 = buffers.getHeader();
|
||||
Buffer b1 = buffers.getBuffer();
|
||||
Buffer b2 = buffers.getBuffer();
|
||||
Buffer b3 = buffers.getBuffer(128);
|
||||
List<Buffer> known = new ArrayList<Buffer>();
|
||||
known.add(h1);
|
||||
known.add(h2);
|
||||
known.add(b1);
|
||||
known.add(b2);
|
||||
known.add(h1);
|
||||
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(h2);
|
||||
buffers.returnBuffer(b1);
|
||||
buffers.returnBuffer(b2);
|
||||
buffers.returnBuffer(b3);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
buffer=buffers.getHeader();
|
||||
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
|
||||
assertTrue(h2==buffers.getBuffer()); // h2 used from buffer slot
|
||||
assertTrue(b3==buffers.getBuffer()); // b1 from other slot
|
||||
buffer=buffers.getBuffer(128);
|
||||
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
|
||||
|
||||
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(h2);
|
||||
buffers.returnBuffer(b1);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
buffer=buffers.getHeader();
|
||||
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
|
||||
assertTrue(h2==buffers.getBuffer()); // h2 used from buffer slot
|
||||
assertTrue(b1==buffers.getBuffer()); // h2 used from other slot
|
||||
|
||||
buffers.returnBuffer(h1);
|
||||
buffers.returnBuffer(b1);
|
||||
buffers.returnBuffer(h2);
|
||||
|
||||
assertTrue(h1==buffers.getHeader()); // pooled header
|
||||
assertTrue(h2==buffers.getHeader()); // h2 from other slot
|
||||
buffer=buffers.getHeader();
|
||||
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
|
||||
assertTrue(b1==buffers.getBuffer()); // b1 used from buffer slot
|
||||
buffer=buffers.getBuffer();
|
||||
for (Buffer b:known) assertTrue(b!=buffer); // new buffer
|
||||
|
||||
|
||||
}
|
||||
|
||||
static class HeaderBuffer extends ByteArrayBuffer
|
||||
{
|
||||
public HeaderBuffer(int size)
|
||||
{
|
||||
super(size);
|
||||
}
|
||||
}
|
||||
|
||||
static class InnerBuffers extends ThreadLocalBuffers
|
||||
{
|
||||
@Override
|
||||
@ -114,13 +232,16 @@ public class ThreadLocalBuffersTest
|
||||
{
|
||||
return new ByteArrayBuffer( size );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Buffer newHeader(int size)
|
||||
{
|
||||
return new ByteArrayBuffer( size );
|
||||
return new HeaderBuffer( size );
|
||||
}
|
||||
@Override
|
||||
protected boolean isHeader(Buffer buffer)
|
||||
{
|
||||
return buffer instanceof HeaderBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,6 +130,18 @@ public abstract class AbstractConnector extends HttpBuffers implements Connector
|
||||
{
|
||||
return new ByteArrayBuffer(size);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isRequestHeader(Buffer buffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isResponseHeader(Buffer buffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
/*
|
||||
|
@ -17,6 +17,7 @@
|
||||
package org.eclipse.jetty.server.nio;
|
||||
|
||||
import org.eclipse.jetty.io.Buffer;
|
||||
import org.eclipse.jetty.io.ByteArrayBuffer;
|
||||
import org.eclipse.jetty.io.nio.DirectNIOBuffer;
|
||||
import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
|
||||
import org.eclipse.jetty.io.nio.NIOBuffer;
|
||||
@ -46,20 +47,6 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements
|
||||
{
|
||||
_useDirectBuffers=direct;
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
// Header buffers always byte array buffers (efficiency of random access)
|
||||
// There are lots of things to consider here... DIRECT buffers are faster to
|
||||
// send but more expensive to build and access! so we have choices to make...
|
||||
// + headers are constructed bit by bit and parsed bit by bit, so INDiRECT looks
|
||||
// good for them.
|
||||
// + but will a gather write of an INDIRECT header with a DIRECT body be any good?
|
||||
// this needs to be benchmarked.
|
||||
// + Will it be possible to get a DIRECT header buffer just for the gather writes of
|
||||
// content from file mapped buffers?
|
||||
// + Are gather writes worth the effort? Maybe they will work well with two INDIRECT
|
||||
// buffers being copied into a single kernel buffer?
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public Buffer newRequestBuffer(int size)
|
||||
@ -82,8 +69,18 @@ public abstract class AbstractNIOConnector extends AbstractConnector implements
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
public Buffer newResponseHeader(int size)
|
||||
{
|
||||
// TODO maybe can be direct?
|
||||
return new IndirectNIOBuffer(size);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isRequestHeader(Buffer buffer)
|
||||
{
|
||||
return buffer instanceof IndirectNIOBuffer;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------------- */
|
||||
protected boolean isResponseHeader(Buffer buffer)
|
||||
{
|
||||
return buffer instanceof IndirectNIOBuffer;
|
||||
}
|
||||
}
|
||||
|
@ -554,6 +554,11 @@ public class SslSelectChannelConnector extends SelectChannelConnector
|
||||
// TODO indirect?
|
||||
return new DirectNIOBuffer(size);
|
||||
}
|
||||
@Override
|
||||
protected boolean isHeader(Buffer buffer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
buffers.setBufferSize(ssl_session.getApplicationBufferSize());
|
||||
buffers.setHeaderSize(ssl_session.getPacketBufferSize());
|
||||
|
Loading…
x
Reference in New Issue
Block a user