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 2017/05/10 07:33:52 UTC
[05/13] httpcomponents-core git commit: HTTPCORE-446: fixed deadlock
in AbstractConnPool shutdown code
HTTPCORE-446: fixed deadlock in AbstractConnPool shutdown code
Project: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/commit/67bcb420
Tree: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/tree/67bcb420
Diff: http://git-wip-us.apache.org/repos/asf/httpcomponents-core/diff/67bcb420
Branch: refs/heads/HTTPCORE-446
Commit: 67bcb4201e4cb2584d298c3c0a0e800c0825f7f3
Parents: 55d881e
Author: Oleg Kalnichevski <ol...@apache.org>
Authored: Wed Feb 15 15:10:22 2017 +0100
Committer: Oleg Kalnichevski <ol...@apache.org>
Committed: Wed Feb 15 15:10:22 2017 +0100
----------------------------------------------------------------------
.../org/apache/http/pool/AbstractConnPool.java | 47 +++++++++++---------
1 file changed, 25 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/httpcomponents-core/blob/67bcb420/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
----------------------------------------------------------------------
diff --git a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
index d34cf24..25a6bfc 100644
--- a/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
+++ b/httpcore/src/main/java/org/apache/http/pool/AbstractConnPool.java
@@ -38,6 +38,8 @@ import java.util.concurrent.ExecutionException;
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, C, E extends PoolEntry<T, C>>
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, C, E extends PoolEntry<T, C>>
@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, C, E extends PoolEntry<T, C>>
}
}
}
- 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);
}