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

Lee Kamentsky leek at broadinstitute.org
Wed Oct 16 14:25:46 CDT 2013


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/816bd180/attachment-0001.html>


More information about the ImageJ-devel mailing list