Posted by
Michael Schmid on
Sep 09, 2020; 1:23pm
URL: http://imagej.273.s1.nabble.com/GenericDialog-and-imagej-lockups-tp5023908p5023918.html
Hi Fred,
trying to answer some of your questions:
> 1) How, using the stack traces, to correlate the "Close" thread
> with the "DICOM_open" thread? I assume the subject resource of
> each of their locks is identified by the number in <>, and they
> are different.
Among the threads in a "WAITING (on object monitor)" state, one of them
is trying to show the GenericDialog, and I guess that this is your problem.
The other suspicious one is "Close"
ij.gui.ImageWindow.close, calling java.awt.Window.dispose
because I would guess that closing an image should be fast and finished
by then.
Looking at it again, I am not so sure. A real deadlock is usually marked
by "BLOCKED (on object monitor)" and I agree that then the numbers in <>
should appear twice. So it
To me, the only other suspicious thing is the "RMI Reaper" #12 related
to a sun.rmi.transport.ObjectTable - a class that I have not idea about.
> Logically why would a GenericDialog care, or even know, about a
> WindowListener of a image window?
I think that adding and removing windows contains operations that have
to be done in *one* queue (one thread, e.g., the EventQueue). So, if
closing one image is not finished it can happen that you can't open
another window.
Your stack trace shows that the 'dispose' of the StackWindow is in the
EventQueue.invokeAndWait: it looks like is blocked because something
else happens on the EventQueue (but strange enough the EventQueue seems
to be idle [parking]).
> Multiple WindowListeners should be allowed
Yes, they are allowed. Just call removeWindowListener for each time you
call addWindowListener, especially if your windowClosing or WindowClosed
callback could do some action that might not be appropriate at a later time.
> 3) "Diffusion_Multimodal exits" is a little nebulous.
What I wanted to say: When everything that you plugin is supposed to do
has finished and there is not need for it being a WindowListener, call
removeWindowListener (preferably before any other cleanup operations,
especially if they might cause WindowListener callbacks)
> 4) I assume that once the Window is closed, all the WindowListeners
> registered for this Window are removed.
Closing has two parts:
(i) "setVisible(false)" has only the effect it says, you can call
"setVisible(true)" and the window will be back again.
(ii) "dispose()" is a bit stronger, but one can still make the window
displayable with pack() or show() as long as a reference to it exists.
I am not sure whether whether dispose() de-registers the
windowListeners; but I fear it doesn't. You may try.
Anyhow, looking at your stack trace again: I see now "windowClosing" or
"windowClosed", so if the problem is related to the WindowListener it
would have to be code that is executed by a WindowListener callback in a
separate thread.
> 5) ... The only thing the WindowListener does is close
> all the results windows.
My feeling is that it is not a good idea to close windows in a
windowClosing() or windowClosed() method (I can't give a clear reason
why). You may try to put this into a separate thread, maybe with
EventQueue.invokeLater, and maybe also add debug messages to see what
actually happens.
But maybe it is also the sun.rmi.transport.ObjectTable issue, in case
closing the results windows somehow calls this class?
In case it is a bug in Java - do you have Oracle or OpenJDK? (and which
version?)
If you have both Oracle and JDK installed, maybe try the other one, to
see whether it could be a java bug.
So far a few more thoughts...
Michael
________________________________________________________________
On 07.09.20 21:51, Fred Damen wrote:
> Greetings Michael,
>
> Questions (asked out of ignorance / not as a challenge) inline...
>
> Thanks,
>
> Fred
>
> On Mon, September 7, 2020 7:25 am, Michael Schmid wrote:
>> Hi Fred,
>>
>> not a clear solution, but one of the threads causing the deadlock is
>> related to closing an image. Please check your WindowListener!
> 1) How, using the stack traces, to correlate the "Close" thread with the
> "DICOM_open" thread? I assume the subject resource of each of their locks
> is identified by the number in <>, and they are different.
> 2) Logically why would a GenericDialog care, or even know, about a
> WindowListener of a image window?, i.e., the WindowListeners are object
> specific and as such they are only called for the window they were
> register against, i.e, not like ImageListeners. At the point of lockup
> there are no other windows, besides the main window, opened.
> 2.1) Multiple WindowListeners should be allowed and called independent of
> thread safety; where the lockup only comes to play when more than one
> thread tries to lock the same resource.
>
>>
>> (1) Is it guaranteed that you call removeWindowListener before
>> Diffusion_Multimodal exits?
> 3) "Diffusion_Multimodal exits" is a little nebulous. The run method that
> was called when Diffusion_Multimodal was run as a plugin has returned. At
> this point the WindowListeners for the source or results windows have not
> been removed. When one of the results windows are closed, the
> WindowListeners (all listeners) are removed for all the results and
source
> windows.
> 3.1) I have included the source code that preforms this, in case someone
> can spot something I missed, n.b., dimp is the same as imp.
> 3.2) I have added this after removing the window listener:
> for(WindowListener wl : dimp.getWindow().getWindowListeners())
> IJ.log("WindowListeners: "+wl);
> and it produced this:
> WindowListeners: Trace - Untitled
> WindowListeners: sun.awt.im.InputMethodContext@5e0e286e
> I assume the first is imagej's (as that is the window title) and the
other
> is Java's WindowListener.
>
>> (Note that it does not hurt to call a 'remove' from a listener too
>> often. It does hurt to call 'add' for a listener more than once, because
>> then the listener will be entered more than once, get callbacks more
>> than once, and must be removed more than once).
> 4) I assume that once the Window is closed, all the WindowListeners
> registered for this Window are removed.
>
>> (2) If Diffusion_Multimodal has ended and its windowClosed or
>> WindowClosing method would get called, could it do something that (i)
>> makes it hang or (ii) leads to something being called on the EventQueue
>> or something that modifies the screen?
> 5) Not that I can tell. The only thing the WindowListener does is close
> all the results windows. The Mouse and Key listeners cause a plot of the
> currently selected voxel. In the testing I did for the posting of this
> issue there is no key or mouse action going on.
> 6) Why would this effect the GenericDialog in the DICOM_open plugin?
>
>> (3) If you use any swing calls (jvax.swing, not AWT), note that swing is
>> not thread-safe. Typically, you should call swing functions only via
>> SwingUtilities.invokeLater.
> 7) The only GUI stuff I used in these two plugin(s) is GenericDialog. I
> included the GenericDialog usage code from DICOM_open.
>
>>
>>
>> Michael
>> ________________________________________________________________
>> On 04.09.20 21:33, Fred Damen wrote:
>>> Greetings,
>>>
>>> I am able to consitently get imagej to lock up, and I am a loss at what
>>> I
>>> am directly or indirectly doing to cause this. The scenario is:
>>> my plugin DICOM_open creates a GenericDialog with an addDialogListener,
>>> which displays and after showDialog returns opens a set of DICOM files
>>> as
>>> a hyperstack. After this I run another plugin, Diffusion_Multimodal,
>>> which creates a GenericDialog and after the showDialog processes this
>>> hyperstack creating a set of images in windows; these windows have
>>> listeners - method that add and removes listener is below. Closing the
>>> hyperstack and running DICOM_open again causes imagej to lockup within
>>> showDialog, see first entry in thread stack traces.
>>>
>>> I can run DICOM_open only, over and over again, without any lockup. I
>>> can
>>> run Diffusion_Multimodal, after the first DICOM_open, over and over
>>> again
>>> without any lockup. Although, running DICOM_open after
>>> Diffusion_Multimodal lockups everytime. I have run this code lots and
>>> lots in the past and do not remember this scenario ever happening.
>>>
>>> I discovered this on release 1.52u14 and confirmed it still happens on
>>> 1.53e14. Any insites and / or suggestion on how to debug this would be
>>> greatly appriciated.
>>>
>>> Thanks in advance,
>>>
>>> Fred
>>
>> --
>> ImageJ mailing list:
http://imagej.nih.gov/ij/list.html >>
>
> --
> ImageJ mailing list:
http://imagej.nih.gov/ij/list.html >
--
ImageJ mailing list:
http://imagej.nih.gov/ij/list.html