[ImageJ-devel] Deadlock: DefaultStatusService.showStatus calls EventService.publish / AbstractColorTool.drawIcon gets active dataset view

Lee Kamentsky leek at broadinstitute.org
Wed Oct 16 15:43:00 CDT 2013


Strange, I've cherrypicked the patch to my master branch of scijava-common
and have successfully run it against the master branch of imagej and I
don't see your error message when I close.

The patch is general and solves the case where you open a sample image and
close - both cases catch the error. I could implement Curtis's suggestion
and mark the status service as closed after dispatch - that's probably the
correct way to do it, but this is pretty robust and does something useful
with status messages sent during shutdown.


On Wed, Oct 16, 2013 at 4:25 PM, Barry DeZonia <bdezonia at gmail.com> wrote:

> Lee,
>
> Using your patch I have an error. Open program and exit and I get this:
>
> java.lang.IllegalStateException: Context already injected:
> org.scijava.AbstractContextual#context
>
> at org.scijava.Context.inject(Context.java:281)
>
> at org.scijava.AbstractContextual.setContext(AbstractContextual.java:66)
>
> at org.scijava.event.DefaultEventService.publishLater(
> DefaultEventService.java:100)
>
> at org.scijava.app.DefaultStatusService.publish(
> DefaultStatusService.java:123)
>
> at org.scijava.app.DefaultStatusService.showStatus(
> DefaultStatusService.java:76)
>
> at imagej.module.ModuleRunner.run(ModuleRunner.java:155)
>
> at imagej.module.ModuleRunner.call(ModuleRunner.java:129)
>
> at imagej.module.ModuleRunner.call(ModuleRunner.java:1)
>
> at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
>
> at java.util.concurrent.FutureTask.run(FutureTask.java:138)
>
> at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(
> ThreadPoolExecutor.java:895)
>
> at java.util.concurrent.ThreadPoolExecutor$Worker.run(
> ThreadPoolExecutor.java:918)
>
> at java.lang.Thread.run(Thread.java:680)
>
>
> Plus said patch will not affect the open sample image and then exit
> crashes. But that may need to be filed as a separate bug.
>
>
> On Wed, Oct 16, 2013 at 3:04 PM, Lee Kamentsky <leek at broadinstitute.org>wrote:
>
>> Maybe I wasn't patient enough about refreshing everything.... will submit
>> patch momentarily, but have only tested it on a modified version of the
>> scijava-common-2.2.0 branch. I'd appreciate you merging and trying it.
>>
>>
>> On Wed, Oct 16, 2013 at 3:54 PM, Barry DeZonia <bdezonia at gmail.com>wrote:
>>
>>> In imagej/pom.xml I added:
>>>
>>>  <scijava-common.version>2.2.1-SNAPSHOT</scijava-common.version>
>>>
>>> in the <properties> section
>>>
>>>
>>> On Wed, Oct 16, 2013 at 2:46 PM, Lee Kamentsky <leek at broadinstitute.org>wrote:
>>>
>>>> Are you editing one of the POMs to pick up the 2.2.1-SNAPSHOT version
>>>> of scijava-common?
>>>>
>>>>
>>>> On Wed, Oct 16, 2013 at 3:45 PM, Barry DeZonia <bdezonia at gmail.com>wrote:
>>>>
>>>>> I'm not having any problems building scijava-common master against IJ2
>>>>> master.
>>>>>
>>>>>
>>>>> On Wed, Oct 16, 2013 at 2:25 PM, Lee Kamentsky <
>>>>> leek at broadinstitute.org> wrote:
>>>>>
>>>>>> I have a very simple fix in scijava-common, but it seems that the
>>>>>> head of the scijava-common master branch is not going to build with the
>>>>>> head of the imagej master branch. How should I proceed? I could branch off
>>>>>> off scijava-common-2.2.0 I suppose.
>>>>>>
>>>>>>
>>>>>> On Wed, Oct 16, 2013 at 2:44 PM, Barry DeZonia <bdezonia at gmail.com>wrote:
>>>>>>
>>>>>>> Thanks. I also updated the ticket a bit a few minutes ago. In my
>>>>>>> second example problem (closing app with sample image open) it looks like
>>>>>>> the original open samples legacy command was not finishing its run. Not
>>>>>>> sure if this is related to your event processing changes.
>>>>>>>
>>>>>>>
>>>>>>> On Wed, Oct 16, 2013 at 1:19 PM, Lee Kamentsky <
>>>>>>> leek at broadinstitute.org> wrote:
>>>>>>>
>>>>>>>> Sorry, I missed it. I'll see if I can take a look at it,
>>>>>>>>
>>>>>>>>
>>>>>>>> On Wed, Oct 16, 2013 at 2:15 PM, Barry DeZonia <bdezonia at gmail.com>wrote:
>>>>>>>>
>>>>>>>>> Lee did you see I reopened ticket #1992 (
>>>>>>>>> http://trac.imagej.net/ticket/1992) that was related to this code
>>>>>>>>> change?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Mon, Oct 7, 2013 at 10:15 AM, Barry DeZonia <bdezonia at gmail.com
>>>>>>>>> > wrote:
>>>>>>>>>
>>>>>>>>>> Merged
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Mon, Sep 30, 2013 at 2:34 PM, Lee Kamentsky <
>>>>>>>>>> leek at broadinstitute.org> wrote:
>>>>>>>>>>
>>>>>>>>>>> I submitted a patch to scijava-common with the changes.
>>>>>>>>>>>
>>>>>>>>>>> https://github.com/scijava/scijava-common/pull/13
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Mon, Sep 30, 2013 at 3:32 PM, Barry DeZonia <
>>>>>>>>>>> bdezonia at gmail.com> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> A proposed fix would be good Lee. I'd like to test the async
>>>>>>>>>>>> status update code for responsiveness (i.e. when opening a large image
>>>>>>>>>>>> let's say). Let me know when your fix is in place. Thanks.
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Sep 27, 2013 at 6:54 AM, Lee Kamentsky <
>>>>>>>>>>>> leek at broadinstitute.org> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Thanks Barry, the email was a little rushed - finished it
>>>>>>>>>>>>> while going out the door. What do you think about sending the status
>>>>>>>>>>>>> messages asynchronously? It looks to me like the AWT event processing will
>>>>>>>>>>>>> display them in the order received, so that makes sure that a "Finished"
>>>>>>>>>>>>> message will be seen after a "% complete" message. Status reporting is such
>>>>>>>>>>>>> a common thing - it'd be a shame for all the worker threads to stall
>>>>>>>>>>>>> because a user was using ImageJ to watch a movie of a cat falling off a TV
>>>>>>>>>>>>> while their batch job was running.
>>>>>>>>>>>>>
>>>>>>>>>>>>> I think I'll submit a patch to DefaultStatusService for asynch
>>>>>>>>>>>>> reporting and maybe Curtis or you could look it over and accept it. If you
>>>>>>>>>>>>> reject, NP.
>>>>>>>>>>>>>
>>>>>>>>>>>>> --Lee
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thu, Sep 26, 2013 at 7:53 PM, Barry DeZonia <
>>>>>>>>>>>>> bdezonia at gmail.com> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi Lee,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I added the synchronized keyword yesterday to fix a bug. We
>>>>>>>>>>>>>> can undo that change. I can work around the problem in another fashion if
>>>>>>>>>>>>>> necessary.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Thu, Sep 26, 2013 at 3:57 PM, Lee Kamentsky <
>>>>>>>>>>>>>> leek at broadinstitute.org> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Hi all, I'm getting a deadly embrace that happens when the
>>>>>>>>>>>>>>> AWT event queue thread tries to get a lock within
>>>>>>>>>>>>>>> DefaultDatasetView.getColor and when DefaultStatusService.showStatus on a
>>>>>>>>>>>>>>> worker thread tries to publish a synchronous request for status display
>>>>>>>>>>>>>>> after taking the DefaultDatasetView's lock in DefaultDatasetView.rebuild.
>>>>>>>>>>>>>>> It happens periodically, but it's timing-dependent, so not so reproducible.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The bug is somewhat debatable. Possible candidates: It's a
>>>>>>>>>>>>>>> little drastic for DefaultDatasetView.getColor to synchronize on the view
>>>>>>>>>>>>>>> itself. Maybe some proxy for the color system could have a synchronizing
>>>>>>>>>>>>>>> object. The other candidate is DefaultEventService.showStatus which could
>>>>>>>>>>>>>>> use EventService.publishLater - I don't think there's much need for status
>>>>>>>>>>>>>>> publishers to wait around for the status to show on the screen.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> The two stack traces:
>>>>>>>>>>>>>>> Thread [AWT-EventQueue-0] (Suspended)
>>>>>>>>>>>>>>> DefaultDatasetView.getColor(ChannelCollection) line: 261 Synchronized
>>>>>>>>>>>>>>> method on DefaultDatasetView
>>>>>>>>>>>>>>>  FgColorTool(AbstractColorTool).drawIcon() line: 175
>>>>>>>>>>>>>>> FgColorTool(AbstractColorTool).onEvent(DisplayActivatedEvent)
>>>>>>>>>>>>>>> line: 184
>>>>>>>>>>>>>>>  NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
>>>>>>>>>>>>>>> line: not available [native method]
>>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>>>>>>>>>>>>>>>  DelegatingMethodAccessorImpl.invoke(Object, Object[])
>>>>>>>>>>>>>>> line: 25
>>>>>>>>>>>>>>> Method.invoke(Object, Object...) line: 597
>>>>>>>>>>>>>>>  DefaultEventService$ProxySubscriber<E>.onEvent(E) line: 282
>>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(Object) line:
>>>>>>>>>>>>>>> 1
>>>>>>>>>>>>>>>  DefaultEventBus(ThreadSafeEventService).publish(Object,
>>>>>>>>>>>>>>> String, Object, List, List, StackTraceElement[]) line: 971
>>>>>>>>>>>>>>>  DefaultEventBus.access$1(DefaultEventBus, Object, String,
>>>>>>>>>>>>>>> Object, List, List, StackTraceElement[]) line: 1
>>>>>>>>>>>>>>> DefaultEventBus$1.run() line: 201
>>>>>>>>>>>>>>>  DefaultThreadService.invoke(Runnable) line: 91
>>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object, String, Object, List,
>>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195
>>>>>>>>>>>>>>>  DefaultEventBus.publishNow(Object) line: 86
>>>>>>>>>>>>>>> DefaultEventService.publish(E) line: 95
>>>>>>>>>>>>>>>  DefaultDisplayService.setActiveDisplay(Display<?>) line:
>>>>>>>>>>>>>>> 129
>>>>>>>>>>>>>>> DefaultDisplayService.onEvent(WinActivatedEvent) line: 247
>>>>>>>>>>>>>>>  NativeMethodAccessorImpl.invoke0(Method, Object, Object[])
>>>>>>>>>>>>>>> line: not available [native method]
>>>>>>>>>>>>>>> NativeMethodAccessorImpl.invoke(Object, Object[]) line: 39
>>>>>>>>>>>>>>>  DelegatingMethodAccessorImpl.invoke(Object, Object[])
>>>>>>>>>>>>>>> line: 25
>>>>>>>>>>>>>>> Method.invoke(Object, Object...) line: 597
>>>>>>>>>>>>>>>  DefaultEventService$ProxySubscriber<E>.onEvent(E) line: 282
>>>>>>>>>>>>>>> DefaultEventService$ProxySubscriber<E>.onEvent(Object) line:
>>>>>>>>>>>>>>> 1
>>>>>>>>>>>>>>>  DefaultEventBus(ThreadSafeEventService).publish(Object,
>>>>>>>>>>>>>>> String, Object, List, List, StackTraceElement[]) line: 971
>>>>>>>>>>>>>>>  DefaultEventBus.access$1(DefaultEventBus, Object, String,
>>>>>>>>>>>>>>> Object, List, List, StackTraceElement[]) line: 1
>>>>>>>>>>>>>>> DefaultEventBus$1.run() line: 201
>>>>>>>>>>>>>>>  DefaultThreadService.invoke(Runnable) line: 91
>>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object, String, Object, List,
>>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195
>>>>>>>>>>>>>>>  DefaultEventBus.publishNow(Object) line: 86
>>>>>>>>>>>>>>> DefaultEventService.publish(E) line: 95
>>>>>>>>>>>>>>>  AWTWindowEventDispatcher.windowActivated(WindowEvent)
>>>>>>>>>>>>>>> line: 94
>>>>>>>>>>>>>>> SwingDisplayWindow(Window).processWindowEvent(WindowEvent)
>>>>>>>>>>>>>>> line: 1877
>>>>>>>>>>>>>>>  SwingDisplayWindow(JFrame).processWindowEvent(WindowEvent)
>>>>>>>>>>>>>>> line: 274
>>>>>>>>>>>>>>> SwingDisplayWindow(Window).processEvent(AWTEvent) line: 1823
>>>>>>>>>>>>>>>  SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 4630
>>>>>>>>>>>>>>> SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 2099
>>>>>>>>>>>>>>>  SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 2478
>>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEvent(AWTEvent) line:
>>>>>>>>>>>>>>> 4460
>>>>>>>>>>>>>>>  DefaultKeyboardFocusManager(KeyboardFocusManager).redispatchEvent(Component,
>>>>>>>>>>>>>>> AWTEvent) line: 1850
>>>>>>>>>>>>>>> DefaultKeyboardFocusManager.typeAheadAssertions(Component,
>>>>>>>>>>>>>>> AWTEvent) line: 910
>>>>>>>>>>>>>>>  DefaultKeyboardFocusManager.dispatchEvent(AWTEvent) line:
>>>>>>>>>>>>>>> 409
>>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 4502
>>>>>>>>>>>>>>>  SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 2099
>>>>>>>>>>>>>>> SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent) line:
>>>>>>>>>>>>>>> 2478
>>>>>>>>>>>>>>>  SwingDisplayWindow(Component).dispatchEvent(AWTEvent)
>>>>>>>>>>>>>>> line: 4460
>>>>>>>>>>>>>>> EventQueue.dispatchEvent(AWTEvent) line: 599
>>>>>>>>>>>>>>>  DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent(SentEvent).dispatch()
>>>>>>>>>>>>>>> line: 55
>>>>>>>>>>>>>>> DefaultKeyboardFocusManager$DefaultKeyboardFocusManagerSentEvent.dispatch()
>>>>>>>>>>>>>>> line: 183
>>>>>>>>>>>>>>>  DefaultKeyboardFocusManager.sendMessage(Component,
>>>>>>>>>>>>>>> AWTEvent) line: 210
>>>>>>>>>>>>>>> DefaultKeyboardFocusManager.dispatchEvent(AWTEvent) line: 286
>>>>>>>>>>>>>>>  SwingDisplayWindow(Component).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 4502
>>>>>>>>>>>>>>> SwingDisplayWindow(Container).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 2099
>>>>>>>>>>>>>>>  SwingDisplayWindow(Window).dispatchEventImpl(AWTEvent)
>>>>>>>>>>>>>>> line: 2478
>>>>>>>>>>>>>>> SwingDisplayWindow(Component).dispatchEvent(AWTEvent) line:
>>>>>>>>>>>>>>> 4460
>>>>>>>>>>>>>>>  EventQueue.dispatchEvent(AWTEvent) line: 599
>>>>>>>>>>>>>>> SequencedEvent.dispatch() line: 101
>>>>>>>>>>>>>>>  EventQueue.dispatchEvent(AWTEvent) line: 597
>>>>>>>>>>>>>>> EventDispatchThread.pumpOneEventForFilters(int) line: 269
>>>>>>>>>>>>>>>  EventDispatchThread.pumpEventsForFilter(int, Conditional,
>>>>>>>>>>>>>>> EventFilter) line: 184
>>>>>>>>>>>>>>> EventDispatchThread.pumpEventsForHierarchy(int, Conditional,
>>>>>>>>>>>>>>> Component) line: 174
>>>>>>>>>>>>>>>  EventDispatchThread.pumpEvents(int, Conditional) line: 169
>>>>>>>>>>>>>>> EventDispatchThread.pumpEvents(Conditional) line: 161
>>>>>>>>>>>>>>>  EventDispatchThread.run() line: 122
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Thread [SciJava-4b2922f6-Thread-27] (Suspended)
>>>>>>>>>>>>>>>  Object.wait(long) line: not available [native method]
>>>>>>>>>>>>>>> EventQueue$1AWTInvocationLock(Object).wait() line: 485 Waiting
>>>>>>>>>>>>>>> for AWT event thread to read invocation request.
>>>>>>>>>>>>>>>  EventQueue.invokeAndWait(Runnable) line: 993
>>>>>>>>>>>>>>> DefaultThreadService.invoke(Runnable) line: 95
>>>>>>>>>>>>>>>  DefaultEventBus.publishNow(Object, String, Object, List,
>>>>>>>>>>>>>>> List, StackTraceElement[]) line: 195
>>>>>>>>>>>>>>> DefaultEventBus.publishNow(Object) line: 86
>>>>>>>>>>>>>>>  DefaultEventService.publish(E) line: 95
>>>>>>>>>>>>>>> DefaultStatusService.showStatus(int, int, String) line: 77
>>>>>>>>>>>>>>>  DefaultMinMaxMethod<T>.report() line: 296
>>>>>>>>>>>>>>> DefaultMinMaxMethod<T>.process() line: 155
>>>>>>>>>>>>>>>  DefaultAutoscaleMethod<T>.getRange(IterableInterval<T>)
>>>>>>>>>>>>>>> line: 70
>>>>>>>>>>>>>>> DefaultAutoscaleService.getDefaultIntervalRange(IterableInterval<RealType<?>>)
>>>>>>>>>>>>>>> line: 97
>>>>>>>>>>>>>>>  DefaultAutoscaleService.getDefaultRandomAccessRange(RandomAccessibleInterval<RealType<?>>)
>>>>>>>>>>>>>>> line: 105
>>>>>>>>>>>>>>>  DefaultDatasetView.autoscale(int) line: 176
>>>>>>>>>>>>>>> DefaultDatasetView.initializeView(boolean) line: 499
>>>>>>>>>>>>>>>  DefaultDatasetView.rebuild() line: 383 Takes the
>>>>>>>>>>>>>>> DefaultDatasetView lock.
>>>>>>>>>>>>>>> DefaultImageDisplay.rebuild() line: 140
>>>>>>>>>>>>>>>  DefaultImageDisplay.display(Object) line: 273
>>>>>>>>>>>>>>> DefaultOverlayService.addOverlays(ImageDisplay,
>>>>>>>>>>>>>>> List<Overlay>) line: 148
>>>>>>>>>>>>>>>  TurboRegRegister.run() line: 144
>>>>>>>>>>>>>>> CommandModule.run() line: 196
>>>>>>>>>>>>>>>  ModuleRunner.run() line: 168
>>>>>>>>>>>>>>> ModuleRunner.call() line: 129
>>>>>>>>>>>>>>>  ModuleRunner.call() line: 1
>>>>>>>>>>>>>>> FutureTask$Sync.innerRun() line: 303
>>>>>>>>>>>>>>>  FutureTask<V>.run() line: 138
>>>>>>>>>>>>>>> ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
>>>>>>>>>>>>>>>  ThreadPoolExecutor$Worker.run() line: 908
>>>>>>>>>>>>>>> Thread.run() line: 662
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> ImageJ-devel mailing list
>>>>>>>>>>>>>>> ImageJ-devel at imagej.net
>>>>>>>>>>>>>>> http://imagej.net/mailman/listinfo/imagej-devel
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://imagej.net/pipermail/imagej-devel/attachments/20131016/bf2dcbbf/attachment-0001.html>


More information about the ImageJ-devel mailing list