hc-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ol...@apache.org
Subject svn commit: r1783929 - /httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
Date Tue, 21 Feb 2017 20:00:33 GMT
Author: olegk
Date: Tue Feb 21 20:00:33 2017
New Revision: 1783929

URL: http://svn.apache.org/viewvc?rev=1783929&view=rev
Log:
HTTPCORE-446: fixed deadlock in AbstractConnPool shutdown code

Modified:
    httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java

Modified: httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java?rev=1783929&r1=1783928&r2=1783929&view=diff
==============================================================================
--- httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
(original)
+++ httpcomponents/httpcore/branches/4.4.x/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
Tue Feb 21 20:00:33 2017
@@ -38,6 +38,8 @@ import java.util.concurrent.ExecutionExc
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -190,37 +192,37 @@ public abstract class AbstractConnPool<T
 
         return new Future<E>() {
 
-            private volatile boolean cancelled;
-            private volatile boolean done;
-            private volatile E entry;
+            private final AtomicBoolean cancelled = new AtomicBoolean(false);
+            private final AtomicBoolean done = new AtomicBoolean(false);
+            private final AtomicReference<E> entryRef = new AtomicReference<E>(null);
 
             @Override
             public boolean cancel(final boolean mayInterruptIfRunning) {
-                cancelled = true;
-                lock.lock();
-                try {
-                    condition.signalAll();
-                } finally {
-                    lock.unlock();
-                }
-                synchronized (this) {
-                    final boolean result = !done;
-                    done = true;
+                if (cancelled.compareAndSet(false, true)) {
+                    done.set(true);
+                    lock.lock();
+                    try {
+                        condition.signalAll();
+                    } finally {
+                        lock.unlock();
+                    }
                     if (callback != null) {
                         callback.cancelled();
                     }
-                    return result;
+                    return true;
+                } else {
+                    return false;
                 }
             }
 
             @Override
             public boolean isCancelled() {
-                return cancelled;
+                return cancelled.get();
             }
 
             @Override
             public boolean isDone() {
-                return done;
+                return done.get();
             }
 
             @Override
@@ -234,6 +236,7 @@ public abstract class AbstractConnPool<T
 
             @Override
             public E get(final long timeout, final TimeUnit tunit) throws InterruptedException,
ExecutionException, TimeoutException {
+                final E entry = entryRef.get();
                 if (entry != null) {
                     return entry;
                 }
@@ -250,16 +253,16 @@ public abstract class AbstractConnPool<T
                                     }
                                 }
                             }
-                            entry = leasedEntry;
-                            done = true;
-                            onLease(entry);
+                            entryRef.set(leasedEntry);
+                            done.set(true);
+                            onLease(leasedEntry);
                             if (callback != null) {
-                                callback.completed(entry);
+                                callback.completed(leasedEntry);
                             }
-                            return entry;
+                            return leasedEntry;
                         }
                     } catch (IOException ex) {
-                        done = true;
+                        done.set(true);
                         if (callback != null) {
                             callback.failed(ex);
                         }



Mime
View raw message