I'm afraid I have to again correct my observations on Bug #1487099. I was
looking at the LayerManager class this morning and realized that the method
causing Pedro's ConcurrentModificationException hasn't yet been fixed by
creating a copy of the LayerListener collection. This fix was applied by Jon
Aquino to some other methods.
After chewing over the problem for a while last night I realize that
creating a copy of the LayerListener collection stored by the LayerManager
class isn't a totally "thread safe" solution to this problem. It does
eliminate the possibility of the ConcurrentModificationExceptions but I
think it would allow a LayerListener to be sent an event when it should not
receive them.
Let me give a quick example of this scenario.
I did a little work on a Data Source Catalog that allows the user to
associate Layers and DataSources. As part of this extension for OpenJUMP I
might have created a LayerListener that presents a dialog box to the user
when a layer is deleted, or removed from the LayerManager. This dialog box
would ask the user if they would also like to delete any DataSources
associated with the Layer. Similarly, the LayerListener might present a
dialog box when a Layer is added to the LayerManager asking the user if they
would like to associate the new Layer with a DataSource.
These 2 dialog boxes could get a little irritating, so I might include an
option that allows the user to turn it "off". This could easily be done by
removing the LayerListener from the LayerManager. This might also be done
programatically by other plug-ins that add or remove layers as part of their
operation.
Here is the problem.
The user performs some action that will cause a Layer to be added or removed
from the LayerManager. When this happens the LayerManager creates a copy of
the LayerListeners collection and begins to iterate over it calling the
appropriate methods of the LayerListeners in a new thread.
The user then performs another action while this thread is running that
causes one of the LayerListeners to be removed from the LayerManager's
collection of LayerListeners. This LayerListener has not been removed from
the copy of the LayerListener collection that is being manipulated by the
thread created previously when a Layer was added or removed. That means the
LayerManager will pass the LayerChanged event to a LayerListener that is no
longer supposed to receive this event because it is present in the copied
collection. (It is no longer present in the original LayerListener
collection.)
I know this would be a rare occurence, but it is possible. I think it leaves
the potential for some hard-to-locate bugs in the future. I believe this
problem can be solved in a thread safe way by restricting access the the
LayerListeners collection with synchronized methods.
Like I said, I'm no expert at threads, and If I'm not understanding this
correctly I'd really appreciate some help!
If my theory about this situation isn't all messed up I'll get started on
the "thread safe" solution for the next release of OpenJUMP. I'll work with
Vivid Solutions to get it incorporated into JUMP as well.
Thanks for any input on this situation.
The Sunburned Surveyor
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Jump-pilot-devel mailing list
Jump-pilot-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jump-pilot-devel