You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by dj...@apache.org on 2013/04/02 23:50:39 UTC

svn commit: r1463768 - in /felix/trunk/scr/src: main/java/org/apache/felix/scr/impl/manager/ test/java/org/apache/felix/scr/integration/ test/java/org/apache/felix/scr/integration/components/felix3680_2/

Author: djencks
Date: Tue Apr  2 21:50:39 2013
New Revision: 1463768

URL: http://svn.apache.org/r1463768
Log:
FELIX-4011 move edge info tracking to component context

Added:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java
Modified:
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
    felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java
    felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/AbstractComponentManager.java Tue Apr  2 21:50:39 2013
@@ -851,6 +851,8 @@ public abstract class AbstractComponentM
         m_dependenciesCollected = false;
     }
 
+    abstract EdgeInfo getEdgeInfo( S implObject, DependencyManager<S, ?> dependencyManager);
+    
     abstract <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount );
 
     abstract <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount );
@@ -966,9 +968,10 @@ public abstract class AbstractComponentM
         // If this component has got dependencies, create dependency managers for each one of them.
         if ( metadata.getDependencies().size() != 0 )
         {
+            int index = 0;
             for ( ReferenceMetadata currentdependency: metadata.getDependencies() )
             {
-                DependencyManager depmanager = new DependencyManager( this, currentdependency );
+                DependencyManager depmanager = new DependencyManager( this, currentdependency, index++ );
 
                 depMgrList.add( depmanager );
             }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentContextImpl.java Tue Apr  2 21:50:39 2013
@@ -19,6 +19,7 @@
 package org.apache.felix.scr.impl.manager;
 
 
+import java.util.Arrays;
 import java.util.Dictionary;
 
 import org.apache.felix.scr.component.ExtComponentContext;
@@ -35,14 +36,31 @@ import org.osgi.service.component.Compon
  */
 public class ComponentContextImpl implements ExtComponentContext, ComponentInstance {
 
-    private AbstractComponentManager m_componentManager;
+    private final AbstractComponentManager m_componentManager;
+    
+    private final EdgeInfo[] edgeInfos;
 
 
     ComponentContextImpl( AbstractComponentManager componentManager )
     {
         m_componentManager = componentManager;
+        edgeInfos = new EdgeInfo[componentManager.getComponentMetadata().getDependencies().size()];
+    }
+    
+    EdgeInfo getEdgeInfo(DependencyManager dm)
+    {
+        int index = dm.getIndex();
+        if (edgeInfos[index] == null)
+        {
+            edgeInfos[index] = new EdgeInfo();
+        }
+        return edgeInfos[index];
     }
 
+    void clearEdgeInfos()
+    {
+        Arrays.fill( edgeInfos, null );
+    }
 
     protected AbstractComponentManager getComponentManager()
     {

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ComponentFactoryImpl.java Tue Apr  2 21:50:39 2013
@@ -123,7 +123,7 @@ public class ComponentFactoryImpl<S> ext
         cm.activateInternal( getTrackingCount().get() );
 
         instance = cm.getComponentInstance();
-        if ( instance == null )
+        if ( instance == null || instance.getInstance() == null )
         {
             // activation failed, clean up component manager
             cm.disposeInternal( ComponentConstants.DEACTIVATION_REASON_DISPOSED );
@@ -278,6 +278,11 @@ public class ComponentFactoryImpl<S> ext
         return true;
     }
 
+    EdgeInfo getEdgeInfo( S implObject, DependencyManager<S, ?> dependencyManager) 
+    {
+        return null;
+    }
+
     <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<T> ref, int trackingCount )
     {
     }

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/DependencyManager.java Tue Apr  2 21:50:39 2013
@@ -67,6 +67,8 @@ public class DependencyManager<S, T> imp
 
     // Reference to the metadata
     private final ReferenceMetadata m_dependencyMetadata;
+    
+    private final int m_index;
 
     private final AtomicReference<ServiceTracker<T, RefPair<T>>> trackerRef = new AtomicReference<ServiceTracker<T, RefPair<T>>>();
 
@@ -82,50 +84,16 @@ public class DependencyManager<S, T> imp
 
     private boolean registered;
 
-    private final Map<S, EdgeInfo> edgeInfoMap = new IdentityHashMap<S, EdgeInfo>(  );
-
-    private static class EdgeInfo
-    {
-        private int open = -1;
-        private int close = -1;
-        private CountDownLatch latch;
-
-        public void setClose( int close )
-        {
-            this.close = close;
-        }
-
-        public CountDownLatch getLatch()
-        {
-            return latch;
-        }
-
-        public void setLatch( CountDownLatch latch )
-        {
-            this.latch = latch;
-        }
-
-        public void setOpen( int open )
-        {
-            this.open = open;
-        }
-
-        public boolean outOfRange( int trackingCount )
-        {
-            return (open != -1 && trackingCount < open)
-                || (close != -1 && trackingCount > close);
-        }
-    }
-
     /**
      * Constructor that receives several parameters.
-     *
      * @param dependency An object that contains data about the dependency
+     * @param index TODO
      */
-    DependencyManager( AbstractComponentManager<S> componentManager, ReferenceMetadata dependency )
+    DependencyManager( AbstractComponentManager<S> componentManager, ReferenceMetadata dependency, int index )
     {
         m_componentManager = componentManager;
         m_dependencyMetadata = dependency;
+        m_index = index;
         customizer = newCustomizer();
 
         // dump the reference information if DEBUG is enabled
@@ -140,6 +108,11 @@ public class DependencyManager<S, T> imp
                             dependency.getCardinality(), dependency.getBind(), dependency.getUnbind() }, null );
         }
     }
+    
+    int getIndex() 
+    {
+        return m_index;
+    }   
 
     /**
      * Initialize binding methods.
@@ -1383,14 +1356,9 @@ public class DependencyManager<S, T> imp
 
     private EdgeInfo getEdgeInfo( S componentInstance )
     {
-        EdgeInfo info = edgeInfoMap.get( componentInstance );
-        if ( info == null )
-        {
-            info = new EdgeInfo();
-            edgeInfoMap.put( componentInstance, info );
-        }
-        return info;
+        return m_componentManager.getEdgeInfo( componentInstance, this );
     }
+    
     /**
      * Revoke the given bindings. This method cannot throw an exception since
      * it must try to complete all that it can
@@ -1427,11 +1395,6 @@ public class DependencyManager<S, T> imp
         latch.countDown();
     }
 
-    void cleanup( S componentInstance)
-    {
-        edgeInfoMap.remove( componentInstance );
-    }
-
     public void invokeBindMethodLate( final ServiceReference<T> ref, int trackingCount )
     {
         if ( !isSatisfied() )
@@ -1497,8 +1460,8 @@ public class DependencyManager<S, T> imp
         {
             synchronized ( trackerRef.get().tracked() )
             {
-                EdgeInfo info = edgeInfoMap.get( componentInstance );
-                if (info != null && info.outOfRange( trackingCount ) )
+                EdgeInfo info = getEdgeInfo( componentInstance );
+                if (info.outOfRange( trackingCount ) )
                 {
                     //ignore events before open started or we will have duplicate binds.
                     return true;
@@ -1556,8 +1519,8 @@ public class DependencyManager<S, T> imp
             }
             synchronized ( trackerRef.get().tracked() )
             {
-                EdgeInfo info = edgeInfoMap.get( componentInstance );
-                if (info != null && info.outOfRange( trackingCount ) )
+                EdgeInfo info = getEdgeInfo( componentInstance );
+                if (info.outOfRange( trackingCount ) )
                 {
                     //ignore events after close started or we will have duplicate unbinds.
                     return;
@@ -1608,9 +1571,9 @@ public class DependencyManager<S, T> imp
             EdgeInfo info;
             synchronized ( trackerRef.get().tracked() )
             {
-                info = edgeInfoMap.get( componentInstance );
+                info = getEdgeInfo( componentInstance );
             }
-            if (info != null && info.outOfRange( trackingCount ) )
+            if (info.outOfRange( trackingCount ) )
             {
                 //wait for unbinds to complete
                 if (info.getLatch() != null)

Added: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java?rev=1463768&view=auto
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java (added)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/EdgeInfo.java Tue Apr  2 21:50:39 2013
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.scr.impl.manager;
+
+import java.util.concurrent.CountDownLatch;
+
+class EdgeInfo
+{
+    private int open = -1;
+    private int close = -1;
+    private CountDownLatch latch;
+
+    public void setClose( int close )
+    {
+        this.close = close;
+    }
+
+    public CountDownLatch getLatch()
+    {
+        return latch;
+    }
+
+    public void setLatch( CountDownLatch latch )
+    {
+        this.latch = latch;
+    }
+
+    public void setOpen( int open )
+    {
+        this.open = open;
+    }
+
+    public boolean outOfRange( int trackingCount )
+    {
+        return (open != -1 && trackingCount < open)
+            || (close != -1 && trackingCount > close);
+    }
+}
\ No newline at end of file

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ImmediateComponentManager.java Tue Apr  2 21:50:39 2013
@@ -121,11 +121,11 @@ public class ImmediateComponentManager<S
         if ( m_implementationObject == null )
         {
             final ComponentContextImpl tmpContext = new ComponentContextImpl( this );
+            m_componentContext = tmpContext;
             S tmpComponent = createImplementationObject( tmpContext, new SetImplementationObject<S>()
             {
                 public void setImplementationObject( S implementationObject )
                 {
-                    m_componentContext = tmpContext;
                     m_implementationObject = implementationObject;
                     m_tmpImplementationObject = null;
                 }
@@ -172,7 +172,7 @@ public class ImmediateComponentManager<S
             m_tmpImplementationObject = implementationObject;
             m_implementationObject = null;
             disposeImplementationObject( implementationObject, m_componentContext, reason );
-            m_implementationObject = null;
+            m_tmpImplementationObject = null;
             cleanupImplementationObject( implementationObject );
             log( LogService.LOG_DEBUG, "Unset and deconfigured implementation object for component {0} in deleteComponent for reason {1}", new Object[] { getName(), REASONS[ reason ] },  null );
             m_componentContext = null;
@@ -342,12 +342,7 @@ public class ImmediateComponentManager<S
 
     protected void cleanupImplementationObject( Object implementationObject )
     {
-
-        for ( DependencyManager md: getReversedDependencyManagers() )
-        {
-            md.cleanup( implementationObject );
-        }
-
+        m_componentContext.clearEdgeInfos();
     }
 
     State getSatisfiedState()
@@ -359,11 +354,10 @@ public class ImmediateComponentManager<S
     {
         return Active.getInstance();
     }
-
-    <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
+    
+    EdgeInfo getEdgeInfo( S implObject, DependencyManager<S, ?> dependencyManager) 
     {
-        final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
-        dependencyManager.invokeUpdatedMethod( impl, refPair, trackingCount );
+        return m_componentContext.getEdgeInfo( dependencyManager );
     }
 
     <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
@@ -372,6 +366,12 @@ public class ImmediateComponentManager<S
         dependencyManager.invokeBindMethod( impl, refPair, trackingCount );
     }
 
+    <T> void invokeUpdatedMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
+    {
+        final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;
+        dependencyManager.invokeUpdatedMethod( impl, refPair, trackingCount );
+    }
+
     <T> void invokeUnbindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> oldRefPair, int trackingCount )
     {
         final S impl = ( m_tmpImplementationObject != null ) ? m_tmpImplementationObject : m_implementationObject;

Modified: felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java (original)
+++ felix/trunk/scr/src/main/java/org/apache/felix/scr/impl/manager/ServiceFactoryComponentManager.java Tue Apr  2 21:50:39 2013
@@ -143,7 +143,6 @@ public class ServiceFactoryComponentMana
             {
                 serviceContext.setImplementationObject( implementationObject );
                 serviceContexts.put( implementationObject, serviceContext );
-
             }
 
 
@@ -201,6 +200,16 @@ public class ServiceFactoryComponentMana
         }
     }
 
+    EdgeInfo getEdgeInfo( S implObject, DependencyManager<S, ?> dependencyManager) 
+    {
+        return serviceContexts.get( implObject ).getEdgeInfo( dependencyManager );
+    }
+
+    protected void cleanupImplementationObject( Object implementationObject )
+    {
+        serviceContexts.get( implementationObject ).clearEdgeInfos();
+    }
+
     <T> void invokeBindMethod( DependencyManager<S, T> dependencyManager, RefPair<T> refPair, int trackingCount )
     {
         for ( S implementationObject : serviceContexts.keySet() )

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/ComponentTestBase.java Tue Apr  2 21:50:39 2013
@@ -114,7 +114,7 @@ public abstract class ComponentTestBase
 
     protected static boolean NONSTANDARD_COMPONENT_FACTORY_BEHAVIOR = false;
     protected volatile Log log;
-
+    
     //set to true to only get last 1000 lines of log.
     protected static boolean restrictedLogging;
     
@@ -677,6 +677,8 @@ public abstract class ComponentTestBase
         private volatile PrintStream m_realOut;
         private volatile PrintStream m_realErr;
 
+        protected Throwable firstFrameworkThrowable;
+
         private final boolean restrictedLogging;
         private final String[] log = new String[1000];
         private int i = 0;
@@ -732,6 +734,12 @@ public abstract class ComponentTestBase
         {
             return m_warnings;
         }
+        
+        Throwable getFirstFrameworkThrowable()
+        {
+            return firstFrameworkThrowable;
+        }
+
 
 
         public void run()
@@ -767,6 +775,7 @@ public abstract class ComponentTestBase
                         sw.append( System.getProperty( "line.separator" ) );
                         PrintWriter pw = new PrintWriter( sw );
                         entry.getError().printStackTrace( pw );
+                        pw.flush();
                     }
                     if ( restrictedLogging )
                     {
@@ -795,6 +804,10 @@ public abstract class ComponentTestBase
             String msg = getFrameworkEventMessage( eventType );
             int level = ( eventType == FrameworkEvent.ERROR ) ? LogService.LOG_ERROR : LogService.LOG_WARNING;
             log( level, msg, event.getThrowable() );
+            if (event.getThrowable() != null && firstFrameworkThrowable == null)
+            {
+                firstFrameworkThrowable = event.getThrowable();
+            }
         }
 
 

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/Felix3680_2Test.java Tue Apr  2 21:50:39 2013
@@ -63,19 +63,25 @@ public class Felix3680_2Test extends Com
 
 
     @Test
-    public void test_concurrent_injection_with_bundleContext()
+    public void test_concurrent_injection_with_bundleContext() throws Throwable
     {
-        final Component main = findComponentByName( "org.apache.felix.scr.integration.components.felix3680_2.Main" );
-        TestCase.assertNotNull( main );
-        main.enable();
-
-        delay( 30 );
-        main.disable();
-        delay(); //async deactivate
-        for ( Iterator it = log.foundWarnings().iterator(); it.hasNext(); )
+        for ( int i = 0; i < 6; i++ )
         {
-            String message = ( String ) it.next();
-            TestCase.fail( "unexpected warning or error logged: " + message );
+            final Component main = findComponentByName( "org.apache.felix.scr.integration.components.felix3680_2.Main" );
+            TestCase.assertNotNull( main );
+            main.enable();
+            delay( 5 ); //run test for 30 seconds
+            main.disable();
+            delay(); //async deactivate
+            if ( log.getFirstFrameworkThrowable() != null )
+            {
+                throw log.getFirstFrameworkThrowable();
+            }
+            for ( Iterator it = log.foundWarnings().iterator(); it.hasNext(); )
+            {
+                String message = ( String ) it.next();
+                TestCase.fail( "unexpected warning or error logged: " + message );
+            }
         }
     }
 }

Modified: felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java
URL: http://svn.apache.org/viewvc/felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java?rev=1463768&r1=1463767&r2=1463768&view=diff
==============================================================================
--- felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java (original)
+++ felix/trunk/scr/src/test/java/org/apache/felix/scr/integration/components/felix3680_2/Main.java Tue Apr  2 21:50:39 2013
@@ -202,19 +202,29 @@ public class Main implements Runnable
         new Thread( this ).start();
     }
 
-    void stop()
+    void stop() throws InterruptedException
     {
-        running = false;
+        synchronized ( this )
+        {
+            running = false;
+        }
+        if (m_enabledLatch != null) 
+        {
+            m_enabledLatch.await( 1, TimeUnit.MILLISECONDS );
+        }
+        if (m_disabledLatch != null) 
+        {
+            m_disabledLatch.await( 1, TimeUnit.MILLISECONDS );
+        }
     }
 
 
     public void run()
     {
         int loop = 0;
-        while ( running )
+        while ( iterate() )
         {
-            m_enabledLatch = new CountDownLatch( 11 ); // 10 for registrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.bindA
-            m_disabledLatch = new CountDownLatch( 11 ); // 10 for unregistrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.unbindA
+            
 
             RegistrationHelper registry = new RegistrationHelper();
             registry.registerBCDEFGHIJK( m_exec );
@@ -258,6 +268,17 @@ public class Main implements Runnable
         }
     }
 
+
+    private synchronized boolean iterate()
+    {
+        if ( running )
+        {
+            m_enabledLatch = new CountDownLatch( 11 ); // 10 for registrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.bindA
+            m_disabledLatch = new CountDownLatch( 11 ); // 10 for unregistrations of B,C,D,E,F,G,H,I,J,K + 1 for Main.unbindA
+        }
+        return running;
+    }
+
     private String dumpThreads()
     {
         ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();