Skip to content

Commit a1fa734

Browse files
committed
[Edge] Cancel the timer from running when we are done with it
Each use of a timer creates a User Object in Windows, and once we have stopped waiting for our desired event we don't need the cancellation tracking anymore. If there are lots of calls to processOSMessagesUntil, such as repeated browser.setText within the MAXIMUM_OPERATION_TIME (5 second) window, we can end up with a huge growth in the number of User Objects, leading to potential `SWTError: No more handles` errors elsewhere in the client code. Fixes #2806
1 parent 28bb9b4 commit a1fa734

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,14 +551,16 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Consumer
551551
MSG msg = new MSG();
552552
AtomicBoolean timeoutOccurred = new AtomicBoolean();
553553
// The timer call also wakes up the display to avoid being stuck in display.sleep()
554-
display.timerExec((int) MAXIMUM_OPERATION_TIME.toMillis(), () -> timeoutOccurred.set(true));
554+
Runnable runnable = () -> timeoutOccurred.set(true);
555+
display.timerExec((int) MAXIMUM_OPERATION_TIME.toMillis(), runnable);
555556
while (!display.isDisposed() && !condition.get() && !timeoutOccurred.get()) {
556557
if (OS.PeekMessage(msg, 0, 0, 0, OS.PM_NOREMOVE | OS.PM_QS_POSTMESSAGE)) {
557558
display.readAndDispatch();
558559
} else {
559560
display.sleep();
560561
}
561562
}
563+
display.timerExec(-1, runnable);
562564
if (!condition.get()) {
563565
timeoutHandler.accept(createTimeOutException());
564566
}

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import org.eclipse.swt.events.FocusListener;
7878
import org.eclipse.swt.graphics.Point;
7979
import org.eclipse.swt.layout.FillLayout;
80+
import org.eclipse.swt.widgets.Composite;
8081
import org.eclipse.swt.widgets.Display;
8182
import org.eclipse.swt.widgets.Event;
8283
import org.eclipse.swt.widgets.Shell;
@@ -2754,6 +2755,18 @@ public void test_TabTraversalOutOfBrowser() {
27542755
assertTrue(text.isFocusControl());
27552756
}
27562757

2758+
// Regression test for https://github.com/eclipse-platform/eclipse.platform.swt/issues/2806
2759+
@Test
2760+
public void test_TimerRegression_Issue2806() {
2761+
for (int i = 0; i < 10000; i++) {
2762+
browser.setText("Iteration " + i);
2763+
new BrowserFunction(browser, "name");
2764+
}
2765+
new Composite(shell, SWT.NONE);
2766+
processUiEvents();
2767+
2768+
}
2769+
27572770
/* custom */
27582771
/**
27592772
* Wait for passTest to return true. Timeout otherwise.

0 commit comments

Comments
 (0)