Project: SWT
Bug 295483 3.5.x regression: UI randomly freezes
Reported: 2009-11-18 11:13:59 | Status: resolved fixed

User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 Build Identifier: 3555 Creating an ApplicationWindow which is updated by many threads can cause a stall within the display main loop. All UI events will freeze until a Windows event occurs (keyboard/mouse/window activity). The test code (see below) works fine on 3.4.x but not on 3.5.x. Using a modified version of 3.5.x with the Display.foregroundIdleProc method from 3.4.x works. This appears to be an SWT problem - my test case uses a JFace ApplicationWindow as I couldn't get a vanilla Shell to fail in a simple test. Reproducible: Always Steps to Reproduce: Run the code below against 3.5.x SWT/JFace Leave the keyboard and mouse alone, and the application will (usually v. quickly) freeze. Moving the mouse over the window brings the application back to life. Test Code: import org.eclipse.jface.window.ApplicationWindow; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; /** * @author jchown */ public class TestUIThread { private static final int NUM_THREADS = 4; public static void main(String[] args) { final Display display = new Display(); final Label[] labels = new Label[NUM_THREADS]; ApplicationWindow window = new ApplicationWindow(null) { @Override public Control createContents(Composite parent) { Shell shell = getShell(); shell.setText("UI Thread Test"); Composite contents = new Composite(parent, SWT.NONE); contents.setLayout(new GridLayout(1, false)); contents.setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.GRAB_VERTICAL)); for (int i = 0; i < labels.length; i++) { labels[i] = new Label(contents, 0); labels[i].setText("-----------------------------"); labels[i].setLayoutData(new GridData(GridData.FILL_VERTICAL | GridData.GRAB_VERTICAL)); } shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent arg0) { display.dispose(); } }); return contents; } }; window.open(); for (int i = 0; i < labels.length; i++) { final Label label = labels[i]; final String id = "Thread " + (i + 1); Thread thread = new Thread() { int tick = 0; @Override public void run() { while (!label.isDisposed()) { try { sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } display.syncExec(new Runnable() { @Override public void run() { if (!label.isDisposed()) label.setText(id + ":" + tick); } }); tick++; } } }; thread.setDaemon(true); thread.setPriority(Thread.MIN_PRIORITY); thread.start(); } while (!display.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } } }

Files changed in fix:
bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/widgets/Display.java