You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2019/12/26 17:49:27 UTC

[httpcomponents-core] branch bug-fixes updated: BasicClientExchangeHandler to delay resource de-allocation until the response has been fully processed

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch bug-fixes
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git


The following commit(s) were added to refs/heads/bug-fixes by this push:
     new d1355aa  BasicClientExchangeHandler to delay resource de-allocation until the response has been fully processed
d1355aa is described below

commit d1355aa2a9ab01ce3285b92be56fd59fee9df0e3
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Dec 26 18:40:02 2019 +0100

    BasicClientExchangeHandler to delay resource de-allocation until the response has been fully processed
---
 .../nio/support/BasicClientExchangeHandler.java    | 64 ++++++++++++++++------
 1 file changed, 47 insertions(+), 17 deletions(-)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicClientExchangeHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicClientExchangeHandler.java
index d63c505..0cf0f7a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicClientExchangeHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicClientExchangeHandler.java
@@ -57,6 +57,7 @@ public final class BasicClientExchangeHandler<T> implements AsyncClientExchangeH
 
     private final AsyncRequestProducer requestProducer;
     private final AsyncResponseConsumer<T> responseConsumer;
+    private final AtomicBoolean completed;
     private final FutureCallback<T> resultCallback;
     private final AtomicBoolean outputTerminated;
 
@@ -66,6 +67,7 @@ public final class BasicClientExchangeHandler<T> implements AsyncClientExchangeH
             final FutureCallback<T> resultCallback) {
         this.requestProducer = Args.notNull(requestProducer, "Request producer");
         this.responseConsumer = Args.notNull(responseConsumer, "Response consumer");
+        this.completed = new AtomicBoolean(false);
         this.resultCallback = resultCallback;
         this.outputTerminated = new AtomicBoolean(false);
     }
@@ -104,25 +106,40 @@ public final class BasicClientExchangeHandler<T> implements AsyncClientExchangeH
 
             @Override
             public void completed(final T result) {
-                releaseResources();
-                if (resultCallback != null) {
-                    resultCallback.completed(result);
+                if (completed.compareAndSet(false, true)) {
+                    try {
+                        if (resultCallback != null) {
+                            resultCallback.completed(result);
+                        }
+                    } finally {
+                        internalReleaseResources();
+                    }
                 }
             }
 
             @Override
             public void failed(final Exception ex) {
-                releaseResources();
-                if (resultCallback != null) {
-                    resultCallback.failed(ex);
+                if (completed.compareAndSet(false, true)) {
+                    try {
+                        if (resultCallback != null) {
+                            resultCallback.failed(ex);
+                        }
+                    } finally {
+                        internalReleaseResources();
+                    }
                 }
             }
 
             @Override
             public void cancelled() {
-                releaseResources();
-                if (resultCallback != null) {
-                    resultCallback.cancelled();
+                if (completed.compareAndSet(false, true)) {
+                    try {
+                        if (resultCallback != null) {
+                            resultCallback.cancelled();
+                        }
+                    } finally {
+                        internalReleaseResources();
+                    }
                 }
             }
 
@@ -131,9 +148,14 @@ public final class BasicClientExchangeHandler<T> implements AsyncClientExchangeH
 
     @Override
     public void cancel() {
-        releaseResources();
-        if (resultCallback != null) {
-            resultCallback.cancelled();
+        if (completed.compareAndSet(false, true)) {
+            try {
+                if (resultCallback != null) {
+                    resultCallback.cancelled();
+                }
+            } finally {
+                internalReleaseResources();
+            }
         }
     }
 
@@ -158,17 +180,25 @@ public final class BasicClientExchangeHandler<T> implements AsyncClientExchangeH
             requestProducer.failed(cause);
             responseConsumer.failed(cause);
         } finally {
-            releaseResources();
-            if (resultCallback != null) {
-                resultCallback.failed(cause);
+            if (completed.compareAndSet(false, true)) {
+                try {
+                    if (resultCallback != null) {
+                        resultCallback.failed(cause);
+                    }
+                } finally {
+                    internalReleaseResources();
+                }
             }
         }
     }
 
-    @Override
-    public final void releaseResources() {
+    private void internalReleaseResources() {
         requestProducer.releaseResources();
         responseConsumer.releaseResources();
     }
 
+    @Override
+    public final void releaseResources() {
+    }
+
 }