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

Lee Kamentsky leek at broadinstitute.org
Wed Oct 16 15:04:01 CDT 2013


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/519754d1/attachment-0001.html>


More information about the ImageJ-devel mailing list