Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Edge] No more handle exceptions from Edge browser #339

Closed
vogella opened this issue Aug 24, 2022 · 7 comments · Fixed by #660
Closed

[Edge] No more handle exceptions from Edge browser #339

vogella opened this issue Aug 24, 2022 · 7 comments · Fixed by #660
Assignees
Labels
bug Something isn't working edge Edge Browser Windows Happens on Windows OS

Comments

@vogella
Copy link
Contributor

vogella commented Aug 24, 2022

In our RCP application we see no more handle exceptions during startup if we use Edge. This does not happen all the time, there seems to be a race condition or the error is reported incorrectly similar to https://bugs.eclipse.org/bugs/show_bug.cgi?id=576196.

If the user starts again the RCP application, the errors does not happen again, sometimes is takes 3-4 attempts to start the application. We are using latest version from https://developer.microsoft.com/de-de/microsoft-edge/webview2/#download-section, currently 104.0.1293.63 pointing to the download with -Dorg.eclipse.swt.browser.DefaultType=edge -Dorg.eclipse.swt.browser.EdgeDir=c:\PROGRA~1\WebView2 in the runtime arguments.

This happens in the Edge.createmethod, relevant stack trace:

org.eclipse.swt.SWTError: No more handles [0x8007139f]
at org.eclipse.swt.SWT.error(SWT.java:4944)
at org.eclipse.swt.browser.Edge.error(Edge.java:190)
at org.eclipse.swt.browser.Edge.create(Edge.java:343)
at org.eclipse.swt.browser.Browser.<init>(Browser.java:99)
at de.example.rcp.base.views.NavigationPanelView.createPartControl(NavigationPanelView.java:242)

Here is the code which triggers the exception:

		try {
			if (hiddenBrowser == null || hiddenBrowser.isDisposed()) {
				hiddenBrowser = new Browser(bar, SWT.EDGE);
				hiddenBrowser.setBounds(0, 0, 0, 0);
				hiddenBrowser.setVisible(false);
			}
		} catch (Exception  | Error  e) {
			LOG.warn("Unable to create hidden browser", e);
		}

callAndWait seems to spins the event queue, maybe this causes the other thread to sync with main thread and to dispose the composite?

static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
	int[] phr = {COM.S_OK};
	IUnknown completion = newCallback((result, pv) -> {
		phr[0] = (int)result;
		if ((int)result == COM.S_OK) {
			ppv[0] = pv;
			new IUnknown(pv).AddRef();
		}
		return COM.S_OK;
	});
	ppv[0] = 0;
	phr[0] = callable.applyAsInt(completion);
	completion.Release();
	Display display = Display.getCurrent();
	while (phr[0] == COM.S_OK && ppv[0] == 0) {
		if (!display.readAndDispatch()) display.sleep();
	}
	return phr[0];
}

The incorrect behavior reported via https://bugs.eclipse.org/bugs/show_bug.cgi?id=576196 can be reproduced with the following snippet.

	public void createComposite(Composite parent) {
		parent.setLayout(new GridLayout(1, false));

		for (int i = 0; i <= 10; i++) {
			System.out.println("Iteration " + i);
			Composite c = new Composite(parent, SWT.NONE);
			Display.getCurrent().asyncExec(new Runnable() {

				@Override
				public void run() {
					c.dispose();
				}
			});
			Browser browser = null;
			if (!c.isDisposed()) {
				browser = new Browser(c, SWT.EDGE);
			}
			if (browser != null) {
				browser.dispose();
			}
		}

	}

Expected behavior

Correct error message or even better, just working.

Environment:

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

  2. JRE/JDK version

Java 11

Version since

Still present in latest I-Buil

Workaround (or) Additional context

Start again the RCP application.

@vogella
Copy link
Contributor Author

vogella commented Aug 24, 2022

@nnemkin can you have a look? This affects the production environment of one of my clients.

@nnemkin
Copy link
Contributor

nnemkin commented Aug 24, 2022

I remember this one. The root cause is that the loop that fakes synchronous operation (callAndWait above) uses Display.readAndDispatch, which allows asyncExec actions to execute. This blows up when one of those actions does dispose(). I've tried switching the wait to low level OS primitives (GetMessage() etc.), but it broke some other things because asyncExec is also used internally by the Browser to queue event handlers.

I guess the proper fix is remove Display.readAndDispatch from the loop and also remove asyncExec from the Browser implementation. Unfortunately this means that the Browser will have to invent its own asyncExec equivalent to use with its own wait loop. I'll see what can be done.

@nnemkin nnemkin self-assigned this Aug 24, 2022
@nnemkin nnemkin added bug Something isn't working Windows Happens on Windows OS edge Edge Browser labels Aug 24, 2022
@vogella
Copy link
Contributor Author

vogella commented Aug 24, 2022

Thanks @nnemkin

@Destrolaric
Copy link

I can confirm we have something similar since we added edge by default in our client. It happens randomly when opening a browser instance.

@Destrolaric
Copy link

@nnemkin Hi, any progress here?

@mandavaakhilkumar
Copy link

mandavaakhilkumar commented Apr 11, 2023

Hi @nnemkin @vogella any work arounds for this issue ?

@SyntevoAlex
Copy link
Member

To my knowledge, @nnemkin is away. He hasn't contributed anything in last 8 months or so.

HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue May 5, 2023
…platform#339

The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
HeikoKlare added a commit to HeikoKlare/eclipse.platform.swt that referenced this issue May 5, 2023
…platform#339

The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
vogella pushed a commit to HeikoKlare/eclipse.platform.swt that referenced this issue May 10, 2023
…platform#339

The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
vogella pushed a commit to HeikoKlare/eclipse.platform.swt that referenced this issue May 11, 2023
…platform#339

The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
niraj-modi pushed a commit that referenced this issue May 12, 2023
The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
raghucssit pushed a commit to raghucssit/eclipse.platform.swt that referenced this issue Jun 7, 2023
…platform#339

The Edge browser creation uses Display.readAndDispath() to process the
OS events for browser instantiation. When there are other asynchronous
executions scheduled while the browser is being initialized, they may be
processed in between the processing of browser-instantiating OS events
if too much time elapses between them. In case such an asynchronous
execution changes a state that makes the browser instantiation fail,
such as disposing the composite parent of the browser, an exception
occurs.

In order to avoid the processing of asynchronous executions during
browser instantiation, the change ensures that readAndDisplay() is only
called when an OS event is present to be processed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working edge Edge Browser Windows Happens on Windows OS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants