Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [platform-ui-dev] Design Question About Listeners & Event Dispatching


You should absolutely be guarding against this.  A common case is that a listener receives an event, and then decides it no longer needs to listen and removes itself.  The JFace ListenerList class handles this case, but is still not completely thread-safe. There is a thread-safe ListenerList in core, but it's not API (it probably should be): org.eclipse.core.internal.runtime.ListenerList.  Here are some discussions from the last time this topic came up:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=55265
https://bugs.eclipse.org/bugs/show_bug.cgi?id=63271




Douglas Pollock <douglas.pollock@xxxxxxxx>
Sent by: platform-ui-dev-bounces@xxxxxxxxxxx

06/05/2005 02:43 PM

Please respond to
dpollock and "Eclipse Platform UI component developers list."

To
platform-ui-dev@xxxxxxxxxxx
cc
Subject
[platform-ui-dev] Design Question About Listeners & Event        Dispatching





My question is whether it should be expected that the list of listeners can be
modified while executing a listener.  Should we always design for this case?  
In other words, should it be possible for a listener to add or remove a
listener while handling an event?


There is a lot of existing code of the following form, or similar but using
iterators.  In the case of iterators, a ConcurrentModificationException will
be thrown.  In the case of indexed access, subtle bugs can exist where
listeners are skipped or handled twice.

       if (activityListeners != null) {
           for (int i = 0; i < activityListeners.size(); i++) {
               ((IActivityListener) activityListeners.get(i))
                       .activityChanged(activityEvent);
                    }
                }

If we write defensively, then we need to do a copy of some sort to avoid
corrupting the collection.

                int commandListenersSize = commandListeners.size();
       if ((commandListeners != null)
               && (commandListenersSize > 0)) {
           final ICommandListener[] listeners = (ICommandListener[])
commandListeners
                   .toArray(new ICommandListener[commandListenersSize]);
           for (int i = 0; i < commandListenersSize; i++) {
               final ICommandListener listener = listeners[i];
               listener.commandChanged(commandEvent);
           }
       }


Should we expend the effort to hunt down the places where we don't defend
against this case?  Or fix them on a case-by-case basis?



cheers,
d.
_______________________________________________
platform-ui-dev mailing list
platform-ui-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/platform-ui-dev


Back to the top