return identifier;
}
+ /**
+ * Return the list of current listeners. Any caller wishing to use this method
+ * has to make sure the collection remains unchanged while it's executing. This
+ * means the caller has to synchronize externally both the registration and
+ * unregistration process.
+ *
+ * @return the list of current listeners
+ */
@SuppressWarnings({ "rawtypes", "unchecked" })
public Collection<org.opendaylight.controller.md.sal.dom.store.impl.DataChangeListenerRegistration<?>> getListeners() {
- // FIXME: this is not thread-safe and races with listener (un)registration!
return (Collection) listeners;
}
}
/**
- *
* Registers listener on this node.
*
* @param path Full path on which listener is registered.
* @param scope Scope of triggering event.
* @return
*/
- public <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
+ public synchronized <L extends AsyncDataChangeListener<InstanceIdentifier, NormalizedNode<?, ?>>> DataChangeListenerRegistration<L> registerDataChangeListener(final InstanceIdentifier path,
final L listener, final DataChangeScope scope) {
DataChangeListenerRegistration<L> listenerReg = new DataChangeListenerRegistration<L>(path,listener, scope, this);
listeners.add(listenerReg);
+ LOG.debug("Listener {} registered", listener);
return listenerReg;
}
- private void removeListener(final DataChangeListenerRegistration<?> listener) {
+ private synchronized void removeListener(final DataChangeListenerRegistration<?> listener) {
listeners.remove(listener);
+ LOG.debug("Listener {} unregistered", listener);
removeThisIfUnused();
}