diff options
author | Andrey Loskutov | 2018-07-25 14:20:21 +0000 |
---|---|---|
committer | Andrey Loskutov | 2018-07-26 12:26:33 +0000 |
commit | 80249abf1b2bdadea845ea360026d4551a9521d1 (patch) | |
tree | e4b6ec95d4cc7df9089baedc68264921e671cb05 | |
parent | 8b62bd6c5c1038d43fa2d6f2d8fa5422749bbf2e (diff) | |
download | eclipse.platform.swt-80249abf1b2bdadea845ea360026d4551a9521d1.tar.gz eclipse.platform.swt-80249abf1b2bdadea845ea360026d4551a9521d1.tar.xz eclipse.platform.swt-80249abf1b2bdadea845ea360026d4551a9521d1.zip |
Bug 532632 - Display.getShells() should not return disposed shells
Added check to guarantee that the returned array contain only not
disposed Shell objects. Log an error to System.error if disposed Shell
was found in the widgetTable. Clean up all occurrencies of the found
disposed Shell objects from the table (to avoid repeating errors).
Reverted workaround in BusyIndicator from commit
b72ec4ee4a25b3b62b1cea617c5fcc5fd2549359, which is superceeded by this
one.
Change-Id: I4bf4a800271c3c0703534d7f1ac53709a51dfe2c
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
2 files changed, 36 insertions, 16 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BusyIndicator.java b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BusyIndicator.java index 1690e460ff..ba5b7a3d52 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BusyIndicator.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BusyIndicator.java @@ -11,8 +11,6 @@ package org.eclipse.swt.custom; -import java.util.*; - import org.eclipse.swt.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.widgets.*; @@ -59,23 +57,26 @@ public static void showWhile(Display display, Runnable runnable) { Integer busyId = Integer.valueOf(nextBusyId); nextBusyId++; Cursor cursor = display.getSystemCursor(SWT.CURSOR_WAIT); - - Arrays.stream(display.getShells()) - .filter(shell -> !shell.isDisposed() && shell.getData(BUSYID_NAME) == null) - .forEach(shell -> { - shell.setCursor(cursor); - shell.setData(BUSYID_NAME, busyId); - }); + Shell[] shells = display.getShells(); + for (int i = 0; i < shells.length; i++) { + Integer id = (Integer)shells[i].getData(BUSYID_NAME); + if (id == null) { + shells[i].setCursor(cursor); + shells[i].setData(BUSYID_NAME, busyId); + } + } try { runnable.run(); } finally { - Arrays.stream(display.getShells()) - .filter(shell -> !shell.isDisposed() && shell.getData(BUSYID_NAME) == busyId) - .forEach(shell -> { - shell.setCursor(null); - shell.setData(BUSYID_NAME, null); - }); + shells = display.getShells(); + for (int i = 0; i < shells.length; i++) { + Integer id = (Integer)shells[i].getData(BUSYID_NAME); + if (id == busyId) { + shells[i].setCursor(null); + shells[i].setData(BUSYID_NAME, null); + } + } } } } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java index 1463384e21..29f4102b5a 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java @@ -2791,7 +2791,10 @@ public Shell [] getShells () { Shell [] result = new Shell [16]; for (int i = 0; i < widgetTable.length; i++) { Widget widget = widgetTable [i]; - if (widget != null && widget instanceof Shell) { + if (!(widget instanceof Shell)) { + continue; + } + if (!widget.isDisposed()) { int j = 0; while (j < index) { if (result [j] == widget) break; @@ -2805,6 +2808,22 @@ public Shell [] getShells () { } result [index++] = (Shell) widget; } + } else { + // bug 532632: somehow widgetTable got corrupted and we have disposed + // shell entries in the table (at least one). + + // We don't throw an error here because it was not broken here, but + // we at least try to report an error (we have no logging context). + System.err.println ("SWT ERROR: disposed shell detected in the table" + debugInfoForIndex(i)); + + // As of today widgetTable contains *four* entries for the *same* + // Shell instance. If we found one broken, there can be others... + // So we clean here all the occurencies of the leaked shell. + for (int j = i; j < widgetTable.length; j++) { + if(widgetTable[j] == widget) { + widgetTable[j] = null; + } + } } } if (index == result.length) return result; |