From a2df03777d64a1cc2face1011a70effb0b98f133 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Sat, 22 Feb 2014 22:07:30 +0000
Subject: [PATCH] Fix OPENDJ-1348: Various connection pool implementations do not recover if the target server is powered off and restarted

---
 opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java |   28 ++++++++++++++++++----------
 1 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java b/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
index 0f29248..b62bb41 100644
--- a/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
+++ b/opendj-ldap-sdk/src/main/java/org/forgerock/opendj/ldap/HeartBeatConnectionFactory.java
@@ -22,7 +22,7 @@
  *
  *
  *      Copyright 2009-2010 Sun Microsystems, Inc.
- *      Portions copyright 2011-2013 ForgeRock AS.
+ *      Portions copyright 2011-2014 ForgeRock AS.
  */
 
 package org.forgerock.opendj.ldap;
@@ -798,14 +798,14 @@
         }
 
         private void checkForHeartBeat() {
-            if (sync.isHeldExclusively()) {
+            if (sync.isHeld()) {
                 /*
-                 * A heart beat is still in progress, but it should have
-                 * completed by now. Let's avoid aggressively terminating the
-                 * connection, because the heart beat may simply have been
-                 * delayed by a sudden surge of activity. Therefore, only flag
-                 * the connection as failed if no activity has been seen on the
-                 * connection since the heart beat was sent.
+                 * A heart beat or bind/startTLS is still in progress, but it
+                 * should have completed by now. Let's avoid aggressively
+                 * terminating the connection, because the heart beat may simply
+                 * have been delayed by a sudden surge of activity. Therefore,
+                 * only flag the connection as failed if no activity has been
+                 * seen on the connection since the heart beat was sent.
                  */
                 final long currentTimeMillis = timeSource.currentTimeMillis();
                 if (lastResponseTimestamp < (currentTimeMillis - timeoutMS)) {
@@ -916,7 +916,6 @@
             if (sync.tryLockExclusively()) {
                 try {
                     connection.searchAsync(heartBeatRequest, null, heartBeatHandler);
-                    return true;
                 } catch (final IllegalStateException e) {
                     /*
                      * This may happen when we attempt to send the heart beat
@@ -931,7 +930,12 @@
                     releaseHeartBeatLock();
                 }
             }
-            return false;
+            /*
+             * Indicate that a the heartbeat should be checked even if a
+             * bind/startTLS is in progress, since these operations will
+             * effectively act as the heartbeat.
+             */
+            return true;
         }
 
         private <R> R timestamp(final R response) {
@@ -1006,6 +1010,10 @@
             return getState() == LOCKED_EXCLUSIVELY;
         }
 
+        boolean isHeld() {
+            return getState() != 0;
+        }
+
         @Override
         protected boolean tryAcquire(final int ignored) {
             if (compareAndSetState(UNLOCKED, LOCKED_EXCLUSIVELY)) {

--
Gitblit v1.10.0