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

Lee Kamentsky leek at broadinstitute.org
Wed Oct 16 13:19:36 CDT 2013


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


More information about the ImageJ-devel mailing list