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


I have entered an enhancement request against platform runtime to expose their ListenerList as API.  This is not likely to happen for 3.1.  Thanks Bob for this very useful summary of what's out there.  I know there are many places that use their own ad-hoc ArrayList implementation for listeners, almost all of which are likely to have potential threading problems.

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

--



Bob Foster <bob@xxxxxxxxxx>
Sent by: platform-ui-dev-bounces@xxxxxxxxxxx

05/06/2005 07:20 PM

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

To
"Eclipse Platform UI component developers list." <platform-ui-dev@xxxxxxxxxxx>
cc
Subject
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


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


Back to the top