X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-binding-broker%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsal%2Fbinding%2Fimpl%2FNotificationBrokerImpl.java;h=258ba517775a2145f3c3046ebbf08194123a0439;hp=fd0b263f8e51cc1028571906cb54da98b727f5f7;hb=e12bd40c3743a3b840c2d69c0f5f088176aa94b5;hpb=1c337a8918c2da99b71002e1e80d760954282ee7 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(); }