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

There are eight (8) classes named ListenerList and one named ListenersList. A quick search found two ad hoc (ArrayList) listener lists. I looked at one of them (a). Their behaviors are described in the table below. Note that (3,4) are alike, as are (1,5-8). Not as DRY as my humor. 2 looks like the most efficient threadsafe implementation when add/remove is much less frequent than events.

The only behavior common among all of them is they all allow modification of the list during an event. So a list that used an iterator would be, excuse the second pun, exceptional.

    T C M A
1.  N Y Y N
2.  Y N Y N
3.  Y Y Y N
4.  Y Y Y N
5.  N Y Y N
6.  N Y Y N
7.  N Y Y N
8.  N Y Y N
9.  N N Y Y
a.  N N Y *

T - Threadsafe
C - Copy before firing
M - allow Modification during event
A - Add/remove affects current event

1 - org.eclipse.update.internal.core.ListenersList
2 - org.eclipse.core.internal.runtime.ListenerList
3 - org.eclipse.core.internal.variables.ListenerList
4 - org.eclipse.debug.internal.core.ListenerList
5 - org.eclipse.jdt.internal.corext.refactoring.ListenerList
6 - org.eclipse.jdt.internal.launching.ListenerList
7 - org.eclipse.jface.util.ListenerList
8 - org.eclipse.ltk.internal.core.refactoring.ListenerList
9 - org.eclipse.swt.widgets.EventTable
a - org.eclipse.jface.util.DelegatingDragAdapter (ArrayList)

5,6 appear to be duplicates
* - Remove depends on where in list; also remove current
    listener during dragStart will cause next listener
    to be skipped.

Bob Foster

Randy Hudson wrote:

Generally there is nothing in the API which suggests that this would fail. We just had this discussion (read "complaint") on the GEF newsgroup.
http://dev.eclipse.org/newslists/news.eclipse.tools.gef/msg11536.html

But a related question is also interesting. If a listener is *added* during notification, should that listener receive the notification, despite not having been a listener when the event occurred. I am 99% sure that the workbench relies on this behavior from SWT. SWT does not have either of the problems mentioned here because they leave holes in their lists if you remove during notification.

It would be nice if there were a common implementation for managing listeners in a safe and efficient way. It's possible to implement "copy-on-modify" such that additions/deletions occur in constant time.

-Randy



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

05/06/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


------------------------------------------------------------------------

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




Back to the top