Skip to content

Edge: Freeze in Browser#evaluate() if evaluated script calls into SWT #1771

@sratz

Description

@sratz

Describe the bug
With Edge, when using browser.evaluate(script) and script somehow causing a callback into SWT, the evaluate() freezes / hangs in 100% CPU.

To Reproduce

@Test
public void test_EvaluateCallingIntoSwt() throws Exception {
	AtomicBoolean initialLoad = new AtomicBoolean();
	AtomicBoolean openWindowListenerCalled = new AtomicBoolean();
	browser.addProgressListener(ProgressListener.completedAdapter(e -> initialLoad.set(true)));
	browser.addOpenWindowListener(event -> {
		event.required = true; // block default
		openWindowListenerCalled.set(true);
	});
	browser.setText("""
			<button id="button" onClick="window.open('https://eclipse.org');">open eclipse.org</button>
			""");
	waitForPassCondition(initialLoad::get);

	browser.evaluate("""
				document.getElementById("button").click();
			""");

	waitForPassCondition(openWindowListenerCalled::get);
}

Expected behavior
Test succeeds with IE and Edge.

Actual behavior
Test hangs with Edge, succeeds with IE.
Stack trace shows:

Thread [main] (Suspended)	
	org.eclipse.swt.internal.win32.OS.PeekMessage(org.eclipse.swt.internal.win32.MSG, long, int, int, int) line: not available [native method]	
	org.eclipse.swt.browser.Edge.processNextOSMessage() line: 371	
	org.eclipse.swt.browser.Edge.callAndWait(java.lang.String[], java.util.function.ToIntFunction<org.eclipse.swt.internal.ole.win32.IUnknown>) line: 284	
	org.eclipse.swt.browser.Edge.evaluate(java.lang.String) line: 746	
	org.eclipse.swt.browser.Edge(org.eclipse.swt.browser.WebBrowser).evaluate(java.lang.String, boolean) line: 406	
	org.eclipse.swt.browser.Browser.evaluate(java.lang.String, boolean) line: 665	
	org.eclipse.swt.browser.Browser.evaluate(java.lang.String) line: 614	
	org.eclipse.swt.tests.junit.Test_org_eclipse_swt_browser_Browser.test_EvaluateCallingIntoSwt() line: 2700	

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • All OS
    • Windows / Edge
    • Linux
    • macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc)

Additional context
This is a side-effect of #660, where inside Edge.callAndWait()
if (!display.readAndDispatch()) display.sleep();
was replaced with
processNextOSMessage();.

@HeikoKlare:
PR #660 suggest that this was to avoid a out-of-handles during initialization, i.e. inside createEnvironment(), but it also affects the evaluate() call negatively.
Do you think it would be reasonable to keep using display.readAndDispatch() in the latter?

Metadata

Metadata

Assignees

No one assigned

    Labels

    edgeEdge Browser

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions