Skip to content

Commit 1ce2a26

Browse files
committed
WIP: Edge Browser Scheduled Job timeout
1 parent 422f742 commit 1ce2a26

File tree

1 file changed

+54
-18
lines changed
  • bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser

1 file changed

+54
-18
lines changed

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

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
263263
phr[0] = callable.applyAsInt(completion);
264264
// "completion" callback may be called asynchronously,
265265
// so keep processing next OS message that may call it
266-
processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, Display.getCurrent());
266+
processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, Optional.empty(), Display.getCurrent());
267267
completion.Release();
268268
return phr[0];
269269
}
@@ -281,7 +281,7 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
281281
phr[0] = callable.applyAsInt(completion);
282282
// "completion" callback may be called asynchronously,
283283
// so keep processing next OS message that may call it
284-
processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, browser.getDisplay());
284+
processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, Optional.empty(), browser.getDisplay());
285285
completion.Release();
286286
return phr[0];
287287
}
@@ -293,12 +293,32 @@ class WebViewWrapper {
293293
private ICoreWebView2_11 webView_11;
294294
private ICoreWebView2_12 webView_12;
295295
private ICoreWebView2_13 webView_13;
296+
297+
void releaseWebViews() {
298+
if(webView != null) {
299+
webView.Release();
300+
}
301+
if(webView_2 != null) {
302+
webView_2.Release();
303+
}
304+
if(webView_10 != null) {
305+
webView_10.Release();
306+
}
307+
if(webView_11 != null) {
308+
webView_11.Release();
309+
}
310+
if(webView_12 != null) {
311+
webView_12.Release();
312+
}
313+
if(webView_13 != null) {
314+
webView_13.Release();
315+
}
316+
}
296317
}
297318

298319
class WebViewProvider {
299-
300320
private CompletableFuture<WebViewWrapper> webViewWrapperFuture = wakeDisplayAfterFuture(new CompletableFuture<>());
301-
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});;
321+
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});
302322

303323
ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
304324
long[] ppv = new long[1];
@@ -310,15 +330,19 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
310330
webViewWrapper.webView_10 = initializeWebView_10(webView);
311331
webViewWrapper.webView_11 = initializeWebView_11(webView);
312332
webViewWrapper.webView_12 = initializeWebView_12(webView);
313-
webViewWrapper.webView_13 = initializeWebView_13(webView);
314-
webViewWrapperFuture.complete(webViewWrapper);
333+
webViewWrapper.webView_13= initializeWebView_13(webView);
334+
boolean success = webViewWrapperFuture.complete(webViewWrapper);
335+
// Release the webViews if the webViewWrapperFuture has already timed out and completed exceptionally
336+
if(!success && webViewWrapperFuture.isCompletedExceptionally()) {
337+
webViewWrapper.releaseWebViews();
338+
return null;
339+
}
315340
return webView;
316341
}
317342

318343
private void abortInitialization() {
319344
webViewWrapperFuture.cancel(true);
320345
}
321-
322346
private ICoreWebView2_2 initializeWebView_2(ICoreWebView2 webView) {
323347
long[] ppv = new long[1];
324348
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_2, ppv);
@@ -366,13 +390,18 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
366390

367391
private WebViewWrapper getWebViewWrapper(boolean waitForPendingWebviewTasksToFinish) {
368392
if(waitForPendingWebviewTasksToFinish) {
369-
processOSMessagesUntil(lastWebViewTask::isDone, browser.getDisplay());
393+
processOSMessagesUntil(lastWebViewTask::isDone, Optional.empty(), browser.getDisplay());
370394
}
371395
return webViewWrapperFuture.join();
372396
}
373397

398+
void releaseWebView() {
399+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
400+
webViewWrapperFuture.join().releaseWebViews();
401+
}
402+
374403
private WebViewWrapper getWebViewWrapper() {
375-
processOSMessagesUntil(webViewWrapperFuture::isDone, browser.getDisplay());
404+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
376405
return webViewWrapperFuture.join();
377406
}
378407

@@ -457,7 +486,7 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
457486
* events for initialization. Thus, this method does not implement an ordinary
458487
* readAndDispatch loop, but waits for an OS event to be processed.
459488
*/
460-
private static void processOSMessagesUntil(Supplier<Boolean> condition, Display display) {
489+
private static void processOSMessagesUntil(Supplier<Boolean> condition, Optional<Runnable> timeoutHandler, Display display) {
461490
MSG msg = new MSG();
462491
AtomicBoolean timeoutOccurred = new AtomicBoolean();
463492
// The timer call also wakes up the display to avoid being stuck in display.sleep()
@@ -470,10 +499,15 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Display
470499
}
471500
}
472501
if (!condition.get()) {
502+
timeoutHandler.ifPresent(handler -> handler.run());
473503
SWT.error(SWT.ERROR_UNSPECIFIED, null, " Waiting for Edge operation to terminate timed out");
474504
}
475505
}
476506

507+
private static SWTException createTimeOutException() {
508+
return new SWTException(SWT.ERROR_UNSPECIFIED, " Waiting for Edge operation to terminate timed out");
509+
}
510+
477511
static ICoreWebView2CookieManager getCookieManager() {
478512
WebViewEnvironment environmentWrapper = webViewEnvironments.get(Display.getCurrent());
479513
if (environmentWrapper == null) {
@@ -614,7 +648,10 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
614648
switch ((int) result) {
615649
case COM.S_OK:
616650
new IUnknown(pv).AddRef();
617-
setupBrowser((int) result, pv);
651+
boolean success = setupBrowser((int) result, pv);
652+
if(!success) {
653+
initializationRollback.run();
654+
}
618655
break;
619656
case COM.E_WRONG_THREAD:
620657
initializationAbortion.run();
@@ -638,10 +675,13 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
638675
});
639676
}
640677

641-
void setupBrowser(int hr, long pv) {
678+
boolean setupBrowser(int hr, long pv) {
642679
long[] ppv = new long[] {pv};
643680
controller = new ICoreWebView2Controller(ppv[0]);
644681
final ICoreWebView2 webView = webViewProvider.initializeWebView(controller);
682+
if(webView == null) {
683+
return false;
684+
}
645685
webView.get_Settings(ppv);
646686
settings = new ICoreWebView2Settings(ppv[0]);
647687

@@ -741,19 +781,15 @@ void setupBrowser(int hr, long pv) {
741781
if (browser.isFocusControl()) {
742782
browserFocusIn(new Event());
743783
}
784+
return true;
744785
}
745786

746787
void browserDispose(Event event) {
747788
containingEnvironment.instances.remove(this);
748789
webViewProvider.scheduleWebViewTask(() -> {
749-
webViewProvider.getWebView(false).Release();
790+
webViewProvider.releaseWebView();
750791
if (environment2 != null) environment2.Release();
751792
if (settings != null) settings.Release();
752-
if (webViewProvider.isWebView_2Available()) webViewProvider.getWebView_2(false).Release();
753-
if (webViewProvider.isWebView_10Available()) webViewProvider.getWebView_10(false).Release();
754-
if (webViewProvider.isWebView_11Available()) webViewProvider.getWebView_11(false).Release();
755-
if (webViewProvider.isWebView_12Available()) webViewProvider.getWebView_12(false).Release();
756-
if (webViewProvider.isWebView_13Available()) webViewProvider.getWebView_13(false).Release();
757793
if(controller != null) {
758794
// Bug in WebView2. Closing the controller from an event handler results
759795
// in a crash. The fix is to delay the closure with asyncExec.

0 commit comments

Comments
 (0)