Bug 238256 - Eclipse freezes when SWT_AWT bridge is used and a modal AWT dialog is shown during shutdown
Summary: Eclipse freezes when SWT_AWT bridge is used and a modal AWT dialog is shown d...
Status: NEW
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Silenio Quarti CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-06-24 10:46 EDT by Willem Verstraeten CLA
Modified: 2019-09-06 16:14 EDT (History)
1 user (show)

See Also:


Attachments
Eclipse plugin project to reproduce the scenario (8.32 KB, application/zip)
2008-06-24 10:46 EDT, Willem Verstraeten CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Willem Verstraeten CLA 2008-06-24 10:46:48 EDT
Created attachment 105709 [details]
Eclipse plugin project to reproduce the scenario

Build ID: Build id: M20080221-1800

Steps To Reproduce:
1. Show an eclipse view with an SWT_AWT bridge in it.
2. Add a workbenchlistener that shows a modal AWT dialog during preShutDown in an invokeAndWait runnable
3. Close Eclipse

Expected result:
The AWT dialog is shown, and when that is closed, eclipse shuts down.

Actual result:
The Eclipse application freezes, and after a little while a blank dialog (the AWT dialog) is shown. No further interaction is possible


More information:
JRE : 1.6.0_05

As long as the view containing the SWT_AWT bridge was never shown, the dialog works just fine. When the view was shown at least once (and even if it is closed afterwards), Eclipse freezes on shutdown.

This scenario is a simplified case of a real scenario we have at our company, where a 3rd-party legacy application (ie. not modifiable) is being integrated into eclipse that requests some user information on shutdown.

======================================================================
AWT stack trace at the moment of the freeze (retrieved with JConsole):

Name: AWT-EventQueue-0
State: RUNNABLE
Total blocked: 1  Total waited: 3

Stack trace: 
sun.awt.windows.WDialogPeer.showModal(Native Method)
sun.awt.windows.WDialogPeer.realShow(Unknown Source)
sun.awt.windows.WWindowPeer.show(Unknown Source)
java.awt.Dialog.conditionalShow(Unknown Source)
   - locked java.awt.Component$AWTTreeLock@1546c85
java.awt.Dialog.show(Unknown Source)
javax.swing.JOptionPane.showInputDialog(Unknown Source)
javax.swing.JOptionPane.showInputDialog(Unknown Source)
javax.swing.JOptionPane.showInputDialog(Unknown Source)
javax.swing.JOptionPane.showInputDialog(Unknown Source)
com.luciad.test.Startup$2.run(Startup.java:27)
java.awt.event.InvocationEvent.dispatch(Unknown Source)
java.awt.EventQueue.dispatchEvent(Unknown Source)
java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.pumpEvents(Unknown Source)
java.awt.EventDispatchThread.run(Unknown Source)

======================================================================
SWT stack trace during freeze:

Name: main
State: WAITING on java.awt.EventQueue$1AWTInvocationLock@1a9192b
Total blocked: 7  Total waited: 9

Stack trace: 
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:485)
java.awt.EventQueue.invokeAndWait(Unknown Source)
com.luciad.test.Startup$1.preShutdown(Startup.java:25)
org.eclipse.ui.internal.Workbench$7.run(Workbench.java:706)
org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:37)
org.eclipse.core.runtime.Platform.run(Platform.java:857)
org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:46)
org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:199)
org.eclipse.ui.internal.Workbench.firePreShutdown(Workbench.java:704)
org.eclipse.ui.internal.Workbench.busyClose(Workbench.java:844)
org.eclipse.ui.internal.Workbench.access$15(Workbench.java:834)
org.eclipse.ui.internal.Workbench$22.run(Workbench.java:1078)
org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
org.eclipse.ui.internal.Workbench.close(Workbench.java:1076)
org.eclipse.ui.internal.Workbench.close(Workbench.java:1048)
org.eclipse.ui.internal.WorkbenchWindow.busyClose(WorkbenchWindow.java:696)
org.eclipse.ui.internal.WorkbenchWindow.access$0(WorkbenchWindow.java:675)
org.eclipse.ui.internal.WorkbenchWindow$2.run(WorkbenchWindow.java:790)
org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:67)
org.eclipse.ui.internal.WorkbenchWindow.close(WorkbenchWindow.java:788)
org.eclipse.jface.window.Window.handleShellCloseEvent(Window.java:736)
org.eclipse.jface.window.Window$3.shellClosed(Window.java:682)
org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:91)
org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:962)
org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:947)
org.eclipse.swt.widgets.Decorations.closeWidget(Decorations.java:301)
org.eclipse.swt.widgets.Decorations.WM_CLOSE(Decorations.java:1621)
org.eclipse.swt.widgets.Control.windowProc(Control.java:3674)
org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:291)
org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1554)
org.eclipse.swt.widgets.Shell.windowProc(Shell.java:1753)
org.eclipse.swt.widgets.Display.windowProc(Display.java:4351)
org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2260)
org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:456)
org.eclipse.swt.widgets.Control.windowProc(Control.java:3760)
org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:291)
org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1554)
org.eclipse.swt.widgets.Shell.windowProc(Shell.java:1753)
org.eclipse.swt.widgets.Display.windowProc(Display.java:4351)
org.eclipse.swt.internal.win32.OS.DefWindowProcW(Native Method)
org.eclipse.swt.internal.win32.OS.DefWindowProc(OS.java:2260)
org.eclipse.swt.widgets.Shell.callWindowProc(Shell.java:456)
org.eclipse.swt.widgets.Control.windowProc(Control.java:3760)
org.eclipse.swt.widgets.Canvas.windowProc(Canvas.java:291)
org.eclipse.swt.widgets.Decorations.windowProc(Decorations.java:1554)
org.eclipse.swt.widgets.Shell.windowProc(Shell.java:1753)
org.eclipse.swt.widgets.Display.windowProc(Display.java:4351)
org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2265)
org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3291)
org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2389)
org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2353)
org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2219)
org.eclipse.ui.internal.Workbench$4.run(Workbench.java:466)
org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:461)
org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:106)
org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:169)
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:363)
org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
java.lang.reflect.Method.invoke(Unknown Source)
org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:508)
org.eclipse.equinox.launcher.Main.basicRun(Main.java:447)
org.eclipse.equinox.launcher.Main.run(Main.java:1173)
org.eclipse.equinox.launcher.Main.main(Main.java:1148)
======================================================================
Comment 1 Steve Northover CLA 2008-06-24 10:53:57 EDT
Not sure there is much we can do about this.  I'm guessing that WDialogPeer.showModal() is sending a cross thread WM_ message and Eclipse is waiting on a lock and not running the event loop which would allow the cross thread message from AWT to be processed.
Comment 2 Willem Verstraeten CLA 2008-06-24 11:16:42 EDT
(In reply to comment #1)
> Not sure there is much we can do about this.  I'm guessing that
> WDialogPeer.showModal() is sending a cross thread WM_ message and Eclipse is
> waiting on a lock and not running the event loop which would allow the cross
> thread message from AWT to be processed.
> 

Does this mean that it is a bug in Sun's AWT implementation? Ie. do you think there is something that they can do to prevent this deadlock? Because not being able to show a modal dialog during Eclipse shutdown actually prevents the integration of our application in Eclipse.

Btw. I've tried showing the modal dialog outside of an invokeAndWait (ie. just inside the SWT thread) but this didn't work either.
Comment 3 Silenio Quarti CLA 2008-06-25 10:44:45 EDT
Calling invokeAndWait() or syncExec() will most certainly cause deadlocks. Are you able to change your code to something like this:


In com.luciad.test.Startup$1.preShutdown(Startup.java:25):

EventQueue.invokeLater(new Runnable() {
   public void run() {
      //code that shows the dialog;
   }
});
Display display = the SWT display
while (dialogIsUp()) {
    if (!display.readAndDispatch()) display.sleep()
}
Comment 4 Willem Verstraeten CLA 2008-06-25 11:40:32 EDT
With that workaround I managed to get it working, thanks !

By the way, as an alternative way of integrating SWT and AWT, we were trying to pump both event queues on the same thread (the AWT-EventQueue thread). We actually managed to get pretty far for stand-alone SWT applications. In the Eclipse workbench however the readAndDispatch loop is locked locked somewhere in a private method so not readily available, so we didn't manage to make it work for an Eclipse application (yet). I'll try to post the code later this week so you guys can tell if it's a good idea or not :)
Comment 5 Eclipse Webmaster CLA 2019-09-06 16:14:58 EDT
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet.

If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.