diff options
author | Simone Bordet | 2015-01-02 17:43:07 +0000 |
---|---|---|
committer | Simone Bordet | 2015-01-02 17:43:07 +0000 |
commit | 5bed6323c1e1f308a393f74d527e41f4f8fe3182 (patch) | |
tree | 4bb6130e71643a084dca4247a2c29e40cd45ae68 /jetty-fcgi/fcgi-client | |
parent | a85a74bbdc23f18e36e9d3fb8c1c6c29dd4c1301 (diff) | |
download | org.eclipse.jetty.project-5bed6323c1e1f308a393f74d527e41f4f8fe3182.tar.gz org.eclipse.jetty.project-5bed6323c1e1f308a393f74d527e41f4f8fe3182.tar.xz org.eclipse.jetty.project-5bed6323c1e1f308a393f74d527e41f4f8fe3182.zip |
Reworked buffer releasing to ensure that it is always executed before
fillInterested() is called.
This is needed to avoid race conditions where fillInterested()
triggers a new thread entering onFillable() and acquiring a new buffer
while the previous thread is releasing the previous buffer.
Diffstat (limited to 'jetty-fcgi/fcgi-client')
-rw-r--r-- | jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java | 67 |
1 files changed, 37 insertions, 30 deletions
diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java index 3b90ddc4c1..e0575bf1fa 100644 --- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java +++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java @@ -100,61 +100,68 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec @Override public void onFillable() { + buffer = acquireBuffer(); + process(buffer); + } + + private ByteBuffer acquireBuffer() + { HttpClient client = destination.getHttpClient(); ByteBufferPool bufferPool = client.getByteBufferPool(); - buffer = bufferPool.acquire(client.getResponseBufferSize(), true); - process(); + return bufferPool.acquire(client.getResponseBufferSize(), true); } - private void process() + private void releaseBuffer(ByteBuffer buffer) { - if (readAndParse()) - { - HttpClient client = destination.getHttpClient(); - ByteBufferPool bufferPool = client.getByteBufferPool(); - bufferPool.release(buffer); - // Don't linger the buffer around if we are idle. - buffer = null; - } + assert this.buffer == buffer; + HttpClient client = destination.getHttpClient(); + ByteBufferPool bufferPool = client.getByteBufferPool(); + bufferPool.release(buffer); + this.buffer = null; } - private boolean readAndParse() + private void process(ByteBuffer buffer) { - EndPoint endPoint = getEndPoint(); - ByteBuffer buffer = this.buffer; - while (true) + try { - try + EndPoint endPoint = getEndPoint(); + boolean looping = false; + while (true) { - if (parse(buffer)) - return false; + if (!looping && parse(buffer)) + return; int read = endPoint.fill(buffer); - if (LOG.isDebugEnabled()) // Avoid boxing of variable 'read'. + if (LOG.isDebugEnabled()) LOG.debug("Read {} bytes from {}", read, endPoint); + if (read > 0) { if (parse(buffer)) - return false; + return; } else if (read == 0) { + releaseBuffer(buffer); fillInterested(); - return true; + return; } else { + releaseBuffer(buffer); shutdown(); - return true; + return; } + + looping = true; } - catch (Exception x) - { - if (LOG.isDebugEnabled()) - LOG.debug(x); - close(x); - return false; - } + } + catch (Exception x) + { + if (LOG.isDebugEnabled()) + LOG.debug(x); + releaseBuffer(buffer); + close(x); } } @@ -352,7 +359,7 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec { if (LOG.isDebugEnabled()) LOG.debug("Content consumed asynchronously, resuming processing"); - process(); + process(HttpConnectionOverFCGI.this.buffer); } @Override |