Made Generator.Result immutable. Now instead of holding a list and
being mutable, it is a single-linked list that is traversed recursively.
This commit is contained in:
parent
4706ed5d87
commit
98de7500f9
|
@ -77,11 +77,10 @@ public class ClientGenerator extends Generator
|
||||||
int maxCapacity = 4 + 4 + 2 * MAX_PARAM_LENGTH;
|
int maxCapacity = 4 + 4 + 2 * MAX_PARAM_LENGTH;
|
||||||
|
|
||||||
// One FCGI_BEGIN_REQUEST + N FCGI_PARAMS + one last FCGI_PARAMS
|
// One FCGI_BEGIN_REQUEST + N FCGI_PARAMS + one last FCGI_PARAMS
|
||||||
Result result = new Result(byteBufferPool, callback);
|
|
||||||
|
|
||||||
ByteBuffer beginRequestBuffer = byteBufferPool.acquire(16, false);
|
ByteBuffer beginRequestBuffer = byteBufferPool.acquire(16, false);
|
||||||
BufferUtil.clearToFill(beginRequestBuffer);
|
BufferUtil.clearToFill(beginRequestBuffer);
|
||||||
result.add(beginRequestBuffer, true);
|
Result result = new Result(byteBufferPool, callback, beginRequestBuffer, true);
|
||||||
|
|
||||||
// Generate the FCGI_BEGIN_REQUEST frame
|
// Generate the FCGI_BEGIN_REQUEST frame
|
||||||
beginRequestBuffer.putInt(0x01_01_00_00 + request);
|
beginRequestBuffer.putInt(0x01_01_00_00 + request);
|
||||||
|
@ -95,7 +94,7 @@ public class ClientGenerator extends Generator
|
||||||
int capacity = 8 + Math.min(maxCapacity, fieldsLength);
|
int capacity = 8 + Math.min(maxCapacity, fieldsLength);
|
||||||
ByteBuffer buffer = byteBufferPool.acquire(capacity, true);
|
ByteBuffer buffer = byteBufferPool.acquire(capacity, true);
|
||||||
BufferUtil.clearToFill(buffer);
|
BufferUtil.clearToFill(buffer);
|
||||||
result.add(buffer, true);
|
result = result.append(buffer, true);
|
||||||
|
|
||||||
// Generate the FCGI_PARAMS frame
|
// Generate the FCGI_PARAMS frame
|
||||||
buffer.putInt(0x01_04_00_00 + request);
|
buffer.putInt(0x01_04_00_00 + request);
|
||||||
|
@ -133,7 +132,7 @@ public class ClientGenerator extends Generator
|
||||||
|
|
||||||
ByteBuffer lastParamsBuffer = byteBufferPool.acquire(8, false);
|
ByteBuffer lastParamsBuffer = byteBufferPool.acquire(8, false);
|
||||||
BufferUtil.clearToFill(lastParamsBuffer);
|
BufferUtil.clearToFill(lastParamsBuffer);
|
||||||
result.add(lastParamsBuffer, true);
|
result = result.append(lastParamsBuffer, true);
|
||||||
|
|
||||||
// Generate the last FCGI_PARAMS frame
|
// Generate the last FCGI_PARAMS frame
|
||||||
lastParamsBuffer.putInt(0x01_04_00_00 + request);
|
lastParamsBuffer.putInt(0x01_04_00_00 + request);
|
||||||
|
@ -160,6 +159,6 @@ public class ClientGenerator extends Generator
|
||||||
|
|
||||||
public Result generateRequestContent(int request, ByteBuffer content, boolean lastContent, Callback callback)
|
public Result generateRequestContent(int request, ByteBuffer content, boolean lastContent, Callback callback)
|
||||||
{
|
{
|
||||||
return generateContent(request, content, lastContent, callback, FCGI.FrameType.STDIN);
|
return generateContent(request, content, false, lastContent, callback, FCGI.FrameType.STDIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,8 +83,8 @@ public class Flusher
|
||||||
result = queue.poll();
|
result = queue.poll();
|
||||||
}
|
}
|
||||||
active = result;
|
active = result;
|
||||||
List<ByteBuffer> buffers = result.getByteBuffers();
|
ByteBuffer[] buffers = result.getByteBuffers();
|
||||||
endPoint.write(this, buffers.toArray(new ByteBuffer[buffers.size()]));
|
endPoint.write(this, buffers);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ public class Flusher
|
||||||
{
|
{
|
||||||
private ShutdownResult()
|
private ShutdownResult()
|
||||||
{
|
{
|
||||||
super(null, new Adapter());
|
super(null, null, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,8 +19,6 @@
|
||||||
package org.eclipse.jetty.fcgi.generator;
|
package org.eclipse.jetty.fcgi.generator;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.fcgi.FCGI;
|
import org.eclipse.jetty.fcgi.FCGI;
|
||||||
import org.eclipse.jetty.io.ByteBufferPool;
|
import org.eclipse.jetty.io.ByteBufferPool;
|
||||||
|
@ -38,18 +36,18 @@ public class Generator
|
||||||
this.byteBufferPool = byteBufferPool;
|
this.byteBufferPool = byteBufferPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Result generateContent(int id, ByteBuffer content, boolean lastContent, Callback callback, FCGI.FrameType frameType)
|
protected Result generateContent(int id, ByteBuffer content, boolean recycle, boolean lastContent, Callback callback, FCGI.FrameType frameType)
|
||||||
{
|
{
|
||||||
id &= 0xFF_FF;
|
id &= 0xFF_FF;
|
||||||
|
|
||||||
int remaining = content == null ? 0 : content.remaining();
|
int remaining = content == null ? 0 : content.remaining();
|
||||||
Result result = new Result(byteBufferPool, callback);
|
Result result = new Result(byteBufferPool, callback, null, false);
|
||||||
|
|
||||||
while (remaining > 0 || lastContent)
|
while (remaining > 0 || lastContent)
|
||||||
{
|
{
|
||||||
ByteBuffer buffer = byteBufferPool.acquire(8, false);
|
ByteBuffer buffer = byteBufferPool.acquire(8, false);
|
||||||
BufferUtil.clearToFill(buffer);
|
BufferUtil.clearToFill(buffer);
|
||||||
result.add(buffer, true);
|
result = result.append(buffer, true);
|
||||||
|
|
||||||
// Generate the frame header
|
// Generate the frame header
|
||||||
buffer.put((byte)0x01);
|
buffer.put((byte)0x01);
|
||||||
|
@ -67,7 +65,7 @@ public class Generator
|
||||||
int limit = content.limit();
|
int limit = content.limit();
|
||||||
content.limit(content.position() + length);
|
content.limit(content.position() + length);
|
||||||
ByteBuffer slice = content.slice();
|
ByteBuffer slice = content.slice();
|
||||||
result.add(slice, false);
|
result = result.append(slice, recycle);
|
||||||
content.position(content.limit());
|
content.position(content.limit());
|
||||||
content.limit(limit);
|
content.limit(limit);
|
||||||
remaining -= length;
|
remaining -= length;
|
||||||
|
@ -80,42 +78,51 @@ public class Generator
|
||||||
{
|
{
|
||||||
private final ByteBufferPool byteBufferPool;
|
private final ByteBufferPool byteBufferPool;
|
||||||
private final Callback callback;
|
private final Callback callback;
|
||||||
private final List<ByteBuffer> buffers;
|
private final ByteBuffer buffer;
|
||||||
private final List<Boolean> recycles;
|
private final boolean recycle;
|
||||||
|
private final Result previous;
|
||||||
|
|
||||||
public Result(ByteBufferPool byteBufferPool, Callback callback)
|
public Result(ByteBufferPool byteBufferPool, Callback callback, ByteBuffer buffer, boolean recycle)
|
||||||
{
|
{
|
||||||
this(byteBufferPool, callback, new ArrayList<ByteBuffer>(4), new ArrayList<Boolean>(4));
|
this(byteBufferPool, callback, buffer, recycle, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result(Result that)
|
private Result(ByteBufferPool byteBufferPool, Callback callback, ByteBuffer buffer, boolean recycle, Result previous)
|
||||||
{
|
|
||||||
this(that.byteBufferPool, that.callback, that.buffers, that.recycles);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Result(ByteBufferPool byteBufferPool, Callback callback, List<ByteBuffer> buffers, List<Boolean> recycles)
|
|
||||||
{
|
{
|
||||||
this.byteBufferPool = byteBufferPool;
|
this.byteBufferPool = byteBufferPool;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.buffers = buffers;
|
this.buffer = buffer;
|
||||||
this.recycles = recycles;
|
this.recycle = recycle;
|
||||||
|
this.previous = previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(ByteBuffer buffer, boolean recycle)
|
public Result append(ByteBuffer buffer, boolean recycle)
|
||||||
{
|
{
|
||||||
buffers.add(buffer);
|
return new Result(byteBufferPool, null, buffer, recycle, this);
|
||||||
recycles.add(recycle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ByteBuffer> getByteBuffers()
|
public ByteBuffer[] getByteBuffers()
|
||||||
{
|
{
|
||||||
return buffers;
|
return getByteBuffers(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ByteBuffer[] getByteBuffers(int length)
|
||||||
|
{
|
||||||
|
int newLength = length + (buffer == null ? 0 : 1);
|
||||||
|
ByteBuffer[] result;
|
||||||
|
result = previous != null ? previous.getByteBuffers(newLength) : new ByteBuffer[newLength];
|
||||||
|
if (buffer != null)
|
||||||
|
result[result.length - newLength] = buffer;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void succeeded()
|
public void succeeded()
|
||||||
{
|
{
|
||||||
recycle();
|
recycle();
|
||||||
|
if (previous != null)
|
||||||
|
previous.succeeded();
|
||||||
|
if (callback != null)
|
||||||
callback.succeeded();
|
callback.succeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,17 +130,16 @@ public class Generator
|
||||||
public void failed(Throwable x)
|
public void failed(Throwable x)
|
||||||
{
|
{
|
||||||
recycle();
|
recycle();
|
||||||
|
if (previous != null)
|
||||||
|
previous.failed(x);
|
||||||
|
if (callback != null)
|
||||||
callback.failed(x);
|
callback.failed(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void recycle()
|
protected void recycle()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < buffers.size(); ++i)
|
if (recycle)
|
||||||
{
|
|
||||||
ByteBuffer buffer = buffers.get(i);
|
|
||||||
if (recycles.get(i))
|
|
||||||
byteBufferPool.release(buffer);
|
byteBufferPool.release(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -85,20 +85,12 @@ public class ServerGenerator extends Generator
|
||||||
|
|
||||||
buffer.flip();
|
buffer.flip();
|
||||||
|
|
||||||
return new Result(generateContent(request, buffer, false, callback, FCGI.FrameType.STDOUT))
|
return generateContent(request, buffer, true, false, callback, FCGI.FrameType.STDOUT);
|
||||||
{
|
|
||||||
@Override
|
|
||||||
protected void recycle()
|
|
||||||
{
|
|
||||||
super.recycle();
|
|
||||||
byteBufferPool.release(buffer);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Result generateResponseContent(int request, ByteBuffer content, boolean lastContent, Callback callback)
|
public Result generateResponseContent(int request, ByteBuffer content, boolean lastContent, Callback callback)
|
||||||
{
|
{
|
||||||
Result result = generateContent(request, content, lastContent, callback, FCGI.FrameType.STDOUT);
|
Result result = generateContent(request, content, false, lastContent, callback, FCGI.FrameType.STDOUT);
|
||||||
if (lastContent)
|
if (lastContent)
|
||||||
{
|
{
|
||||||
// Generate the FCGI_END_REQUEST
|
// Generate the FCGI_END_REQUEST
|
||||||
|
@ -109,7 +101,7 @@ public class ServerGenerator extends Generator
|
||||||
endRequestBuffer.putInt(0x00_08_00_00);
|
endRequestBuffer.putInt(0x00_08_00_00);
|
||||||
endRequestBuffer.putLong(0x00L);
|
endRequestBuffer.putLong(0x00L);
|
||||||
endRequestBuffer.flip();
|
endRequestBuffer.flip();
|
||||||
result.add(endRequestBuffer, true);
|
result = result.append(endRequestBuffer, true);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class HttpClientTransportOverFCGI extends AbstractHttpClientTransport
|
||||||
|
|
||||||
public HttpClientTransportOverFCGI(String scriptRoot)
|
public HttpClientTransportOverFCGI(String scriptRoot)
|
||||||
{
|
{
|
||||||
this(Runtime.getRuntime().availableProcessors() / 2 + 1, false, scriptRoot);
|
this(Math.max(1, Runtime.getRuntime().availableProcessors() / 2), false, scriptRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpClientTransportOverFCGI(int selectors, boolean multiplexed, String scriptRoot)
|
public HttpClientTransportOverFCGI(int selectors, boolean multiplexed, String scriptRoot)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
org.eclipse.jetty.client.LEVEL=DEBUG
|
#org.eclipse.jetty.client.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.fcgi.LEVEL=DEBUG
|
#org.eclipse.jetty.fcgi.LEVEL=DEBUG
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
org.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
|
||||||
org.eclipse.jetty.client.LEVEL=DEBUG
|
#org.eclipse.jetty.client.LEVEL=DEBUG
|
||||||
org.eclipse.jetty.fcgi.LEVEL=DEBUG
|
#org.eclipse.jetty.fcgi.LEVEL=DEBUG
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class HttpChannelOverFCGI extends HttpChannel<ByteBuffer>
|
||||||
{
|
{
|
||||||
if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(field.getName()))
|
if (FCGI.Headers.REQUEST_METHOD.equalsIgnoreCase(field.getName()))
|
||||||
method = field.getValue();
|
method = field.getValue();
|
||||||
else if (FCGI.Headers.REQUEST_URI.equalsIgnoreCase(field.getName()))
|
else if (FCGI.Headers.DOCUMENT_URI.equalsIgnoreCase(field.getName()))
|
||||||
path = field.getValue();
|
path = field.getValue();
|
||||||
else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(field.getName()))
|
else if (FCGI.Headers.QUERY_STRING.equalsIgnoreCase(field.getName()))
|
||||||
query = field.getValue();
|
query = field.getValue();
|
||||||
|
|
Loading…
Reference in New Issue