X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FNotificationBrokerImpl.java;h=58e46ceca3d14d63bb2dbd6a45feec2417280f21;hb=c74d5c2399e500fe3e690edc8cee497b1cb6f867;hp=fd0b263f8e51cc1028571906cb54da98b727f5f7;hpb=63ebb308c97fc06eafe813c347f9c8d7cde541eb;p=controller.git 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..58e46ceca3 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; @@ -16,19 +19,21 @@ import org.opendaylight.controller.sal.binding.codegen.impl.SingletonHolder; import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.NotificationInvoker; import org.opendaylight.yangtools.concepts.AbstractListenerRegistration; import org.opendaylight.yangtools.concepts.ListenerRegistration; -import org.opendaylight.yangtools.concepts.util.ListenerRegistry; +import org.opendaylight.yangtools.util.ListenerRegistry; import org.opendaylight.yangtools.yang.binding.Notification; 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(); }