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

Barry DeZonia bdezonia at gmail.com
Mon Oct 7 10:15:29 CDT 2013


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/20131007/9790c16c/attachment-0001.html>


More information about the ImageJ-devel mailing list