Fix a synchronized bug when creating Hazelcast channels and
adding or removing channel listeners.

Bug found by Ray.

Change-Id: I7c28ed24915bf3801aeddb88cce6887739c20a3e
diff --git a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
index 3ff46b2..39d6c49 100755
--- a/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
+++ b/src/main/java/net/onrc/onos/datagrid/HazelcastDatagrid.java
@@ -358,11 +358,12 @@
     @Override
     public <K, V> IEventChannel<K, V> createChannel(String channelName,
                                                     Class<K> typeK, Class<V> typeV) {
-        IEventChannel<K, V> eventChannel =
+        synchronized (eventChannels) {
+            IEventChannel<K, V> eventChannel =
                 createChannelImpl(channelName, typeK, typeV);
-        eventChannel.startup();
-
-        return eventChannel;
+            eventChannel.startup();
+            return eventChannel;
+	}
     }
 
     /**
@@ -371,6 +372,7 @@
      * If the channel already exists, just return it.
      * NOTE: The caller must call IEventChannel.startup() to startup the
      * channel operation.
+     * NOTE: The caller must own the lock on "eventChannels".
      *
      * @param channelName the event channel name.
      * @param <K>         the type of the Key in the Key-Value store.
@@ -379,7 +381,7 @@
      * @param typeV       the type of the Value in the Key-Value store.
      * @return the event channel for the channel name.
      */
-    private synchronized <K, V> IEventChannel<K, V> createChannelImpl(
+    private <K, V> IEventChannel<K, V> createChannelImpl(
             String channelName,
             Class<K> typeK, Class<V> typeV) {
         IEventChannel<K, V> castedEventChannel;
@@ -424,12 +426,14 @@
     public <K, V> IEventChannel<K, V> addListener(String channelName,
                                                   IEventChannelListener<K, V> listener,
                                                   Class<K> typeK, Class<V> typeV) {
-        IEventChannel<K, V> eventChannel =
+        synchronized (eventChannels) {
+            IEventChannel<K, V> eventChannel =
                 createChannelImpl(channelName, typeK, typeV);
-        eventChannel.addListener(listener);
-        eventChannel.startup();
+            eventChannel.addListener(listener);
+            eventChannel.startup();
 
-        return eventChannel;
+            return eventChannel;
+	}
     }
 
     /**
@@ -443,18 +447,21 @@
     @Override
     public <K, V> void removeListener(String channelName,
                                       IEventChannelListener<K, V> listener) {
-        IEventChannel<K, V> castedEventChannel;
-        IEventChannel<?, ?> genericEventChannel =
+	synchronized (eventChannels) {
+            IEventChannel<?, ?> genericEventChannel =
                 eventChannels.get(channelName);
 
-        if (genericEventChannel != null) {
-            //
-            // TODO: Find if we can use Java internal support to check for
-            // type mismatch.
-            // NOTE: Using "ClassCastException" exception below doesn't work.
-            //
-            castedEventChannel = (IEventChannel<K, V>) genericEventChannel;
-            castedEventChannel.removeListener(listener);
+            if (genericEventChannel != null) {
+                //
+                // TODO: Find if we can use Java internal support to check for
+                // type mismatch.
+                // NOTE: Using "ClassCastException" exception below doesn't
+                // work.
+                //
+                IEventChannel<K, V> castedEventChannel =
+                    (IEventChannel<K, V>) genericEventChannel;
+                castedEventChannel.removeListener(listener);
+            }
         }
     }