Filter registered listeners 70/88170/1
authorRobert Varga <robert.varga@pantheon.tech>
Sat, 29 Feb 2020 11:18:28 +0000 (12:18 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Sat, 29 Feb 2020 15:44:57 +0000 (16:44 +0100)
There is a small race window where the registration could be marked
as unregistered and not removed from the map. Check that condition
before letting the listener through.

Change-Id: I1938e6459faaaadf69bc7907ba6ba71e65fe9e8f
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
common/util/src/main/java/org/opendaylight/yangtools/util/ListenerRegistry.java

index ca1b79af06884a0839dfd4de2bc89c0e2186b06d..964eb196fd7148c43157de16a67d3fd6322c4b81 100644 (file)
@@ -27,8 +27,7 @@ import org.opendaylight.yangtools.concepts.Mutable;
  * @param <T> Type of listeners this registry handles
  */
 public final class ListenerRegistry<T extends EventListener> implements Mutable {
-
-    private final Set<ListenerRegistration<? extends T>> listeners = ConcurrentHashMap.newKeySet();
+    private final Set<RegistrationImpl<? extends T>> listeners = ConcurrentHashMap.newKeySet();
     // This conversion is known to be safe.
     @SuppressWarnings({ "rawtypes", "unchecked" })
     private final Set<ListenerRegistration<T>> unmodifiableView = (Set) Collections.unmodifiableSet(listeners);
@@ -53,7 +52,7 @@ public final class ListenerRegistry<T extends EventListener> implements Mutable
     }
 
     public void clear() {
-        listeners.stream().forEach(ListenerRegistration::close);
+        listeners.stream().forEach(RegistrationImpl::close);
     }
 
     public boolean isEmpty() {
@@ -61,11 +60,11 @@ public final class ListenerRegistry<T extends EventListener> implements Mutable
     }
 
     public Stream<? extends T> streamListeners() {
-        return listeners.stream().map(ListenerRegistration::getInstance);
+        return listeners.stream().filter(RegistrationImpl::notClosed).map(RegistrationImpl::getInstance);
     }
 
     public <L extends T> @NonNull ListenerRegistration<L> register(final L listener) {
-        final ListenerRegistration<L> ret = new ListenerRegistrationImpl<>(listener, listeners);
+        final RegistrationImpl<L> ret = new RegistrationImpl<>(listener, listeners);
         listeners.add(ret);
         return ret;
     }
@@ -78,11 +77,10 @@ public final class ListenerRegistry<T extends EventListener> implements Mutable
                 .toString();
     }
 
-    private static final class ListenerRegistrationImpl<T extends EventListener>
-            extends AbstractListenerRegistration<T> {
+    private static final class RegistrationImpl<T extends EventListener> extends AbstractListenerRegistration<T> {
         private Collection<?> removeFrom;
 
-        ListenerRegistrationImpl(final T instance, final Collection<?> removeFrom) {
+        RegistrationImpl(final T instance, final Collection<?> removeFrom) {
             super(instance);
             this.removeFrom = requireNonNull(removeFrom);
         }