#7284 cleanup HttpInput reopen/recycle
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
parent
c7cec39ff5
commit
44fb63e541
|
@ -31,6 +31,7 @@ import org.slf4j.LoggerFactory;
|
|||
class AsyncContentProducer implements ContentProducer
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AsyncContentProducer.class);
|
||||
private static final HttpInput.ErrorContent RECYCLED_ERROR_CONTENT = new HttpInput.ErrorContent(new IllegalStateException("ContentProducer has been recycled"));
|
||||
private static final Throwable UNCONSUMED_CONTENT_EXCEPTION = new IOException("Unconsumed content")
|
||||
{
|
||||
@Override
|
||||
|
@ -66,9 +67,30 @@ class AsyncContentProducer implements ContentProducer
|
|||
assertLocked();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("recycling {}", this);
|
||||
|
||||
// Make sure that the content has been fully consumed before destroying the interceptor and also make sure
|
||||
// that asking this instance for content between recycle and reopen will only produce error'ed content.
|
||||
if (_rawContent == null)
|
||||
_rawContent = RECYCLED_ERROR_CONTENT;
|
||||
else if (!_rawContent.isSpecial())
|
||||
throw new IllegalStateException("ContentProducer with unconsumed content cannot be recycled");
|
||||
|
||||
if (_transformedContent == null)
|
||||
_transformedContent = RECYCLED_ERROR_CONTENT;
|
||||
else if (!_transformedContent.isSpecial())
|
||||
throw new IllegalStateException("ContentProducer with unconsumed content cannot be recycled");
|
||||
|
||||
if (_interceptor instanceof Destroyable)
|
||||
((Destroyable)_interceptor).destroy();
|
||||
_interceptor = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reopen()
|
||||
{
|
||||
assertLocked();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("reopening {}", this);
|
||||
_rawContent = null;
|
||||
_transformedContent = null;
|
||||
_error = false;
|
||||
|
|
|
@ -46,6 +46,14 @@ class BlockingContentProducer implements ContentProducer
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("recycling {}", this);
|
||||
_asyncContentProducer.recycle();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reopen()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("reopening {}", this);
|
||||
_asyncContentProducer.reopen();
|
||||
_semaphore.drainPermits();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
package org.eclipse.jetty.server;
|
||||
|
||||
import org.eclipse.jetty.util.component.Destroyable;
|
||||
import org.eclipse.jetty.util.thread.AutoLock;
|
||||
|
||||
/**
|
||||
|
@ -27,17 +28,24 @@ import org.eclipse.jetty.util.thread.AutoLock;
|
|||
public interface ContentProducer
|
||||
{
|
||||
/**
|
||||
* Lock this instance. The lock must be held before any method of this instance's
|
||||
* method be called, and must be manually released afterward.
|
||||
* Lock this instance. The lock must be held before any of this instance's
|
||||
* method can be called, and must be released afterward.
|
||||
* @return the lock that is guarding this instance.
|
||||
*/
|
||||
AutoLock lock();
|
||||
|
||||
/**
|
||||
* Reset all internal state and clear any held resources.
|
||||
* Clear the interceptor and call {@link Destroyable#destroy()} on it if it implements {@link Destroyable}.
|
||||
* A recycled {@link ContentProducer} will only produce special content with a non-null error until
|
||||
* {@link #reopen()} is called.
|
||||
*/
|
||||
void recycle();
|
||||
|
||||
/**
|
||||
* Reset all internal state, making this is instance logically equivalent to a freshly allocated one.
|
||||
*/
|
||||
void reopen();
|
||||
|
||||
/**
|
||||
* Fail all content currently available in this {@link ContentProducer} instance
|
||||
* as well as in the underlying {@link HttpChannel}.
|
||||
|
|
|
@ -55,8 +55,12 @@ public class HttpInput extends ServletInputStream implements Runnable
|
|||
|
||||
public void recycle()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("recycle {}", this);
|
||||
try (AutoLock lock = _contentProducer.lock())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("recycle {}", this);
|
||||
_blockingContentProducer.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
public void reopen()
|
||||
|
@ -65,7 +69,7 @@ public class HttpInput extends ServletInputStream implements Runnable
|
|||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("reopen {}", this);
|
||||
_blockingContentProducer.recycle();
|
||||
_blockingContentProducer.reopen();
|
||||
_contentProducer = _blockingContentProducer;
|
||||
_consumedEof = false;
|
||||
_readListener = null;
|
||||
|
|
Loading…
Reference in New Issue