Index: src/main/java/org/apache/http/impl/nio/client/DefaultClientExchangeHandlerImpl.java =================================================================== --- src/main/java/org/apache/http/impl/nio/client/DefaultClientExchangeHandlerImpl.java (revision 1616169) +++ src/main/java/org/apache/http/impl/nio/client/DefaultClientExchangeHandlerImpl.java (working copy) @@ -107,12 +107,13 @@ this.requestProducer.close(); } catch (final IOException ex) { this.log.debug("I/O error closing request producer", ex); + } finally { + try { + this.responseConsumer.close(); + } catch (final IOException ex) { + this.log.debug("I/O error closing response consumer", ex); + } } - try { - this.responseConsumer.close(); - } catch (final IOException ex) { - this.log.debug("I/O error closing response consumer", ex); - } } public void start() throws HttpException, IOException { @@ -152,15 +153,14 @@ final ContentDecoder decoder, final IOControl ioctrl) throws IOException { this.exec.consumeContent(this.state, decoder, ioctrl); if (!decoder.isCompleted() && this.responseConsumer.isDone()) { - if (this.completed.compareAndSet(false, true)) { - try { - this.resultFuture.cancel(); - } finally { - responseConsumer.close(); - } + try { + this.state.setNonReusable(); + this.completed.set(true); + releaseConnection(); + this.resultFuture.cancel(); + } finally { + close(); } - this.state.setNonReusable(); - releaseConnection(); } } Index: src/test/java/org/apache/http/nio/client/integration/TestHttpAsyncPrematureTermination.java =================================================================== --- src/test/java/org/apache/http/nio/client/integration/TestHttpAsyncPrematureTermination.java (revision 1616169) +++ src/test/java/org/apache/http/nio/client/integration/TestHttpAsyncPrematureTermination.java (working copy) @@ -33,6 +33,7 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.http.HttpConnection; import org.apache.http.HttpException; @@ -53,6 +54,7 @@ import org.apache.http.nio.entity.NStringEntity; import org.apache.http.nio.protocol.BasicAsyncRequestConsumer; import org.apache.http.nio.protocol.BasicAsyncRequestHandler; +import org.apache.http.nio.protocol.BasicAsyncRequestProducer; import org.apache.http.nio.protocol.BasicAsyncResponseProducer; import org.apache.http.nio.protocol.HttpAsyncExchange; import org.apache.http.nio.protocol.HttpAsyncRequestConsumer; @@ -300,28 +302,32 @@ final HttpHost target = start(); - final HttpAsyncRequestProducer producer = HttpAsyncMethods.create(target, new HttpGet("/")); + final AtomicInteger producerClosed = new AtomicInteger(0); + final AtomicInteger consumerClosed = new AtomicInteger(0); - final AtomicBoolean closed = new AtomicBoolean(false); - final AtomicBoolean cancelled = new AtomicBoolean(false); - final AtomicBoolean failed = new AtomicBoolean(false); + final HttpAsyncRequestProducer producer = new BasicAsyncRequestProducer(target, new HttpGet("/")) { + @Override + public synchronized void close() throws IOException { + producerClosed.incrementAndGet(); + super.close(); + } + }; + final HttpAsyncResponseConsumer consumer = new HttpAsyncResponseConsumer() { @Override public void close() throws IOException { - closed.set(true); + consumerClosed.incrementAndGet(); } @Override public boolean cancel() { - cancelled.set(true); return false; } @Override public void failed(final Exception ex) { - failed.set(true); } public void responseReceived( @@ -355,8 +361,9 @@ connMgr.shutdown(1000); Assert.assertTrue(future.isCancelled()); - Assert.assertFalse(failed.get()); - Assert.assertTrue(closed.get()); + + Assert.assertEquals(1, producerClosed.get()); + Assert.assertEquals(1, consumerClosed.get()); } }