From 4f425a29d8c7115f8014f7548db560400c850e41 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 14 Sep 2012 23:11:07 +0000
Subject: [PATCH] Fix OPENDJ-590: ConnectionPool may return already closed/disconnected connections
---
opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java | 58 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 33 insertions(+), 25 deletions(-)
diff --git a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
index 5f5acc8..1cde3f2 100644
--- a/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
+++ b/opendj3/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/FixedConnectionPool.java
@@ -575,36 +575,44 @@
@Override
public FutureResult<Connection> getConnectionAsync(
final ResultHandler<? super Connection> handler) {
- QueueElement holder;
- synchronized (queue) {
- if (isClosed) {
- throw new IllegalStateException("FixedConnectionPool is already closed");
+ // Loop while iterating through stale connections (see OPENDJ-590).
+ for (;;) {
+ final QueueElement holder;
+ synchronized (queue) {
+ if (isClosed) {
+ throw new IllegalStateException("FixedConnectionPool is already closed");
+ }
+
+ if (queue.isEmpty() || queue.getFirst().isWaitingFuture()) {
+ holder = new QueueElement(handler);
+ queue.add(holder);
+ } else {
+ holder = queue.removeFirst();
+ }
}
- if (queue.isEmpty() || queue.getFirst().isWaitingFuture()) {
- holder = new QueueElement(handler);
- queue.add(holder);
+ if (!holder.isWaitingFuture()) {
+ // There was a completed connection attempt.
+ final Connection connection = holder.getWaitingConnection();
+ if (connection.isValid()) {
+ final PooledConnection pooledConnection = new PooledConnection(connection);
+ if (handler != null) {
+ handler.handleResult(pooledConnection);
+ }
+ return new CompletedFutureResult<Connection>(pooledConnection);
+ } else {
+ // Close the stale connection and try again.
+ connection.close();
+ }
} else {
- holder = queue.removeFirst();
+ // Grow the pool if needed.
+ final FutureResult<Connection> future = holder.getWaitingFuture();
+ if (!future.isDone() && currentPoolSize.tryAcquire()) {
+ factory.getConnectionAsync(connectionResultHandler);
+ }
+ return future;
}
}
-
- if (!holder.isWaitingFuture()) {
- // There was a completed connection attempt.
- final Connection connection = holder.getWaitingConnection();
- final PooledConnection pooledConnection = new PooledConnection(connection);
- if (handler != null) {
- handler.handleResult(pooledConnection);
- }
- return new CompletedFutureResult<Connection>(pooledConnection);
- } else {
- // Grow the pool if needed.
- final FutureResult<Connection> future = holder.getWaitingFuture();
- if (!future.isDone() && currentPoolSize.tryAcquire()) {
- factory.getConnectionAsync(connectionResultHandler);
- }
- return future;
- }
}
/**
--
Gitblit v1.10.0