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 2021/04/02 08:58:55 UTC
[httpcomponents-core] branch 5.1.x updated: Bug fix: fixes race
condition when a connection request completes successfully and times out at
the same time causing a pool entry leak
This is an automated email from the ASF dual-hosted git repository.
olegk pushed a commit to branch 5.1.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git
The following commit(s) were added to refs/heads/5.1.x by this push:
new e849f64 Bug fix: fixes race condition when a connection request completes successfully and times out at the same time causing a pool entry leak
e849f64 is described below
commit e849f6427053c51fe22bfdfb4f7e66fc258af4b3
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Wed Mar 31 16:15:03 2021 +0200
Bug fix: fixes race condition when a connection request completes successfully and times out at the same time causing a pool entry leak
---
.../main/java/org/apache/hc/core5/pool/ConnPool.java | 6 +++++-
.../java/org/apache/hc/core5/pool/LaxConnPool.java | 18 +++++++++++++++++-
.../java/org/apache/hc/core5/pool/StrictConnPool.java | 18 +++++++++++++++++-
3 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/pool/ConnPool.java b/httpcore5/src/main/java/org/apache/hc/core5/pool/ConnPool.java
index 5d648bf..0d50d63 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/pool/ConnPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/pool/ConnPool.java
@@ -46,13 +46,17 @@ public interface ConnPool<T, C extends ModalCloseable> {
/**
* Attempts to lease a connection for the given route and with the given
* state from the pool.
+ * <p>
+ * Please note the connection request can get automatically cancelled by the pool
+ * in case of a request timeout.
*
* @param route route of the connection.
* @param state arbitrary object that represents a particular state
* (usually a security principal or a unique token identifying
* the user whose credentials have been used while establishing the connection).
* May be {@code null}.
- * @param requestTimeout request timeout.
+ * @param requestTimeout request timeout. In case of a timeout the request
+ * can get automatically cancelled by the pool.
* @param callback operation completion callback.
*
* @return future for a leased pool entry.
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java b/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
index 26b56e6..b1d43d0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
@@ -33,7 +33,10 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ConcurrentMap;
+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.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -466,7 +469,20 @@ public class LaxConnPool<T, C extends ModalCloseable> implements ManagedConnPool
final Timeout requestTimeout,
final FutureCallback<PoolEntry<T, C>> callback) {
Asserts.check(!terminated.get(), "Connection pool shut down");
- final BasicFuture<PoolEntry<T, C>> future = new BasicFuture<>(callback);
+ final BasicFuture<PoolEntry<T, C>> future = new BasicFuture<PoolEntry<T, C>>(callback) {
+
+ @Override
+ public synchronized PoolEntry<T, C> get(
+ final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ try {
+ return super.get(timeout, unit);
+ } catch (final TimeoutException ex) {
+ cancel();
+ throw ex;
+ }
+ }
+
+ };
final long releaseState = releaseSeqNum.get();
PoolEntry<T, C> entry = null;
if (pending.isEmpty()) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java b/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
index a222bd8..3ad6cd0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
@@ -34,7 +34,10 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
+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.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -172,7 +175,20 @@ public class StrictConnPool<T, C extends ModalCloseable> implements ManagedConnP
Args.notNull(requestTimeout, "Request timeout");
Asserts.check(!this.isShutDown.get(), "Connection pool shut down");
final Deadline deadline = Deadline.calculate(requestTimeout);
- final BasicFuture<PoolEntry<T, C>> future = new BasicFuture<>(callback);
+ final BasicFuture<PoolEntry<T, C>> future = new BasicFuture<PoolEntry<T, C>>(callback) {
+
+ @Override
+ public synchronized PoolEntry<T, C> get(
+ final long timeout, final TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
+ try {
+ return super.get(timeout, unit);
+ } catch (final TimeoutException ex) {
+ cancel();
+ throw ex;
+ }
+ }
+
+ };
final boolean acquiredLock;
try {