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

Lee Kamentsky leek at broadinstitute.org
Fri Sep 27 06:54:00 CDT 2013


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/20130927/70c6f92e/attachment.html>


More information about the ImageJ-devel mailing list