Bug 576196 - [Edge] No more handle exception from Edge browser during asynchronous dispose
Summary: [Edge] No more handle exception from Edge browser during asynchronous dispose
Status: RESOLVED MOVED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 4.22   Edit
Hardware: PC Windows 10
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Nikita Nemkin CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 575660
  Show dependency tree
 
Reported: 2021-09-22 09:27 EDT by Lars Vogel CLA
Modified: 2022-08-24 04:30 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lars Vogel CLA 2021-09-22 09:27:38 EDT
A client of mine uses the Edge browser. He also uses RxJava to trigger asynchronously the recreation of the user interface.

If this happens to fast, we see sometimes a NO_MORE_HANDLERS exception. This happens in Edge#create


hr = callAndWait(ppv, completion -> environment.CreateCoreWebView2Controller(browser.handle, completion));
if (hr != COM.S_OK) error(SWT.ERROR_NO_HANDLES, hr);

The return code of hr is -2147023496

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];
}
Comment 1 Lars Vogel CLA 2021-09-22 09:36:32 EDT
The situation can simulated with the following code:

	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();
			}
		}

	}
Comment 2 Lars Vogel CLA 2021-09-22 09:36:58 EDT
Nikita, can you have a look?
Comment 3 Nikita Nemkin CLA 2021-09-22 15:44:08 EDT
(In reply to Lars Vogel from comment #2)
> Nikita, can you have a look?

I'll have a look.
Comment 4 Lars Vogel CLA 2021-11-09 08:07:41 EST
(In reply to Nikita Nemkin from comment #3)
> (In reply to Lars Vogel from comment #2)
> > Nikita, can you have a look?
> 
> I'll have a look.

Any progress, here?