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 <l...@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 <bdezo...@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 >> <l...@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@imagej.net >>> http://imagej.net/mailman/listinfo/imagej-devel >>> >>> >> >
_______________________________________________ ImageJ-devel mailing list ImageJ-devel@imagej.net http://imagej.net/mailman/listinfo/imagej-devel