From: Robert Varga Date: Mon, 2 Jun 2014 13:46:28 +0000 (+0200) Subject: BUG-1120: fold GenerationalListenerMap back X-Git-Tag: release/helium~719^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=e12bd40c3743a3b840c2d69c0f5f088176aa94b5 BUG-1120: fold GenerationalListenerMap back This moves needless indirection code form GenerationalListenerMap back to NotificaitonBrokerImpl. Now the contract is directly between NotificationBrokerImpl and ListenerMapGeneration Change-Id: I0b401fa4b10e06afbc7206323d1c1f4afb19d422 Signed-off-by: Robert Varga --- diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java deleted file mode 100644 index 85265e8fd4..0000000000 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/GenerationalListenerMap.java +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ -package org.opendaylight.controller.sal.binding.impl; - -import java.util.concurrent.atomic.AtomicReference; - -import javax.annotation.concurrent.GuardedBy; - -import org.opendaylight.yangtools.yang.binding.Notification; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; - -/** - * A multi-generation, isolated notification type to listener map. - */ -final class GenerationalListenerMap { - private final AtomicReference current = new AtomicReference<>(new ListenerMapGeneration()); - - Iterable> listenersFor(final Notification notification) { - return current.get().listenersFor(notification); - } - - Iterable> getKnownTypes() { - // Note: this relies on current having immutable listeners - return current.get().getListeners().keySet(); - } - - @GuardedBy("this") - private Multimap, NotificationListenerRegistration> mutableListeners() { - return HashMultimap.create(current.get().getListeners()); - } - - synchronized void addRegistrations(final NotificationListenerRegistration... registrations) { - Multimap, NotificationListenerRegistration> listeners = - mutableListeners(); - - for (NotificationListenerRegistration reg : registrations) { - listeners.put(reg.getType(), reg); - } - - current.set(new ListenerMapGeneration(listeners)); - } - - synchronized void removeRegistrations(final NotificationListenerRegistration... registrations) { - Multimap, NotificationListenerRegistration> listeners = - mutableListeners(); - - for (NotificationListenerRegistration reg : registrations) { - listeners.remove(reg.getType(), reg); - } - - current.set(new ListenerMapGeneration(listeners)); - } -} diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/ListenerMapGeneration.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/ListenerMapGeneration.java index 89e3feeb6f..5ded885f8e 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/ListenerMapGeneration.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/ListenerMapGeneration.java @@ -75,4 +75,8 @@ final class ListenerMapGeneration { return ret; } + + public Iterable> getKnownTypes() { + return listeners.keySet(); + } } \ No newline at end of file diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java index fd0b263f8e..258ba51777 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationBrokerImpl.java @@ -9,6 +9,9 @@ package org.opendaylight.controller.sal.binding.impl; import java.util.Set; import java.util.concurrent.ExecutorService; +import java.util.concurrent.atomic.AtomicReference; + +import javax.annotation.concurrent.GuardedBy; import org.opendaylight.controller.sal.binding.api.NotificationListener; import org.opendaylight.controller.sal.binding.api.NotificationProviderService; @@ -22,13 +25,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Preconditions; +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; public class NotificationBrokerImpl implements NotificationProviderService, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(NotificationBrokerImpl.class); private final ListenerRegistry interestListeners = ListenerRegistry.create(); - private final GenerationalListenerMap listeners = new GenerationalListenerMap(); + private final AtomicReference listeners = new AtomicReference<>(new ListenerMapGeneration()); private final ExecutorService executor; public NotificationBrokerImpl(final ExecutorService executor) { @@ -42,18 +47,44 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto @Override public void publish(final Notification notification, final ExecutorService service) { - for (NotificationListenerRegistration r : listeners.listenersFor(notification)) { + for (NotificationListenerRegistration r : listeners.get().listenersFor(notification)) { service.submit(new NotifyTask(r, notification)); } } + @GuardedBy("this") + private Multimap, NotificationListenerRegistration> mutableListeners() { + return HashMultimap.create(listeners.get().getListeners()); + } + private final void addRegistrations(final NotificationListenerRegistration... registrations) { - listeners.addRegistrations(registrations); + synchronized (this) { + final Multimap, NotificationListenerRegistration> newListeners = + mutableListeners(); + for (NotificationListenerRegistration reg : registrations) { + newListeners.put(reg.getType(), reg); + } + + listeners.set(new ListenerMapGeneration(newListeners)); + } + + // Notifications are dispatched out of lock... for (NotificationListenerRegistration reg : registrations) { announceNotificationSubscription(reg.getType()); } } + private synchronized void removeRegistrations(final NotificationListenerRegistration... registrations) { + final Multimap, NotificationListenerRegistration> newListeners = + mutableListeners(); + + for (NotificationListenerRegistration reg : registrations) { + newListeners.remove(reg.getType(), reg); + } + + listeners.set(new ListenerMapGeneration(newListeners)); + } + private void announceNotificationSubscription(final Class notification) { for (final ListenerRegistration listener : interestListeners) { try { @@ -68,7 +99,8 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto @Override public ListenerRegistration registerInterestListener(final NotificationInterestListener interestListener) { final ListenerRegistration registration = this.interestListeners.register(interestListener); - for (final Class notification : listeners.getKnownTypes()) { + + for (final Class notification : listeners.get().getKnownTypes()) { interestListener.onNotificationSubscribtion(notification); } return registration; @@ -79,7 +111,7 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto final NotificationListenerRegistration reg = new AbstractNotificationListenerRegistration(notificationType, listener) { @Override protected void removeRegistration() { - listeners.removeRegistrations(this); + removeRegistrations(this); } }; @@ -112,7 +144,7 @@ public class NotificationBrokerImpl implements NotificationProviderService, Auto return new AbstractListenerRegistration(listener) { @Override protected void removeRegistration() { - listeners.removeRegistrations(regs); + removeRegistrations(regs); for (ListenerRegistration reg : regs) { reg.close(); }