Bug-3794 - OFHandshake thread leak leads to OOM. 99/22999/1
authorAnil Vishnoi <vishnoianil@gmail.com>
Fri, 19 Jun 2015 13:30:02 +0000 (19:00 +0530)
committerAnil Vishnoi <vishnoianil@gmail.com>
Fri, 19 Jun 2015 16:04:11 +0000 (16:04 +0000)
Fixed the thread pool cleanup

Change-Id: I95f7c8f54f839767c7dddbf47eaee79101cecf59
Signed-off-by: Anil Vishnoi <vishnoianil@gmail.com>
(cherry picked from commit b3e707fd60476c7ebf79b53a198b703eee0030ca)

openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/ConnectionConductorImpl.java

index 25d731e9bf2c6cdab400aef08c403f505a676520..34c57c0cc6870b4fc0b1bafe88b6de94b9e49afd 100644 (file)
@@ -10,10 +10,12 @@ package org.opendaylight.openflowplugin.openflow.md.core;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.util.concurrent.Futures;
+
 import java.util.concurrent.Future;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionAdapter;
 import org.opendaylight.openflowjava.protocol.api.connection.ConnectionReadyListener;
 import org.opendaylight.openflowplugin.api.OFConstants;
@@ -384,6 +386,8 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
      */
     protected void checkState(CONDUCTOR_STATE expectedState) {
         if (!conductorState.equals(expectedState)) {
+            LOG.warn("State of connection to switch {} is not correct, "
+                    + "terminating the connection",connectionAdapter.getRemoteAddress() );
             throw new IllegalStateException("Expected state: " + expectedState
                     + ", actual state:" + conductorState);
         }
@@ -575,11 +579,33 @@ public class ConnectionConductorImpl implements OpenflowProtocolListener,
     @Override
     public void close() {
         conductorState = CONDUCTOR_STATE.RIP;
+        if(handshakeContext != null){
+            try {
+                handshakeContext.close();
+            } catch (Exception e) {
+                LOG.warn("Closing handshake context failed: {}", e.getMessage());
+                LOG.debug("Detail in hanshake context close:", e);
+            }
+        } else {
+            //This condition will occure when Old Helium openflowplugin implementation will be used.
+            shutdownPoolPolitely();
+        }
+    }
+
+    private void shutdownPoolPolitely() {
+        LOG.debug("Terminating handshake pool for node {}",connectionAdapter.getRemoteAddress());
+        hsPool.shutdown();
         try {
-            handshakeContext.close();
-        } catch (Exception e) {
-            LOG.warn("Closing handshake context failed: {}", e.getMessage());
-            LOG.debug("Detail in hanshake context close:", e);
+            hsPool.awaitTermination(1, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            LOG.debug("Error while awaiting termination of pool. Will force shutdown now.");
+        } finally {
+            hsPool.purge();
+            if (! hsPool.isTerminated()) {
+                hsPool.shutdownNow();
+            }
+            LOG.debug("is handshake pool for node {} is terminated : {}",
+                    connectionAdapter.getRemoteAddress(), hsPool.isTerminated());
         }
     }