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

Barry DeZonia bdezonia at gmail.com
Wed Oct 16 13:44:37 CDT 2013


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/47a34e87/attachment-0001.html>


More information about the ImageJ-devel mailing list