Skip to content

Commit 596bef6

Browse files
committed
Avoid BusyIndicator putting Display to sleep after being done
Due to a race condition between the BusyIndicator's event loop spinning and the display.wake() call performed after the future to wait for is done, the BusyIndicator execution may get stuck in a display.sleep() call. While on Windows and MacOS the wake() call will effectively still ensure that display.sleep() return immediately if invoked display.sleep() was called, this is neither guaranteed nor does that happen on Linux. This fixes the race condition by replacing the wake() call in the future with scheduling an empty task that ensures that the event queue remains spinned (like everywhere else). Contributes to #3044
1 parent 0f991b5 commit 596bef6

File tree

1 file changed

+9
-3
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom

1 file changed

+9
-3
lines changed

bundles/org.eclipse.swt/Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BusyIndicator.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class BusyIndicator {
3434
static final String BUSYID_NAME = "SWT BusyIndicator"; //$NON-NLS-1$
3535
static final String BUSY_CURSOR = "SWT BusyIndicator Cursor"; //$NON-NLS-1$
3636

37+
private static final Runnable DO_NOTHING = () -> {};
38+
3739
/**
3840
* Runs the given <code>Runnable</code> while providing
3941
* busy feedback using this busy indicator.
@@ -111,10 +113,14 @@ public static void showWhile(Future<?> future) {
111113
stage.handle((nil1, nil2) -> {
112114
if (!display.isDisposed()) {
113115
try {
114-
display.wake();
116+
// Use asyncExec() to wake up the display thread instead of wake()
117+
// as this call may happen between the future.isDone() check and the
118+
// display.sleep() call such that a wake() may get lost whereas an asyncExec()
119+
// will wake up the sleep() even if it is scheduled before calling sleep()
120+
display.asyncExec(DO_NOTHING);
115121
} catch (SWTException e) {
116-
// ignore then, this can happen due to the async nature between our check for
117-
// disposed and the actual call to wake the display can be disposed
122+
// ignore; due to the async nature between our disposed check and scheduling
123+
// asyncExec(), the display may already be disposed
118124
}
119125
}
120126
return null;

0 commit comments

Comments
 (0)