Skip to content

Commit b42a5aa

Browse files
committed
Handling WebViewWrapperFuture on operation timeout
This commit conributes to handle how webViewWrapperFuture should exceptionally complete if there happens an edge operation timeout in processOSMessagesUntil method contributes to eclipse-platform#1466 and eclipse.platform.ui/#2734
1 parent b3e784d commit b42a5aa

File tree

1 file changed

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

1 file changed

+27
-11
lines changed

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

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
264264
phr[0] = callable.applyAsInt(completion);
265265
// "completion" callback may be called asynchronously,
266266
// so keep processing next OS message that may call it
267-
processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, Display.getCurrent());
267+
processOSMessagesUntil(() -> phr[0] != COM.S_OK || ppv[0] != 0, Optional.empty(), Display.getCurrent());
268268
completion.Release();
269269
return phr[0];
270270
}
@@ -282,7 +282,7 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282282
phr[0] = callable.applyAsInt(completion);
283283
// "completion" callback may be called asynchronously,
284284
// so keep processing next OS message that may call it
285-
processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, browser.getDisplay());
285+
processOSMessagesUntil(() -> phr[0] != COM.S_OK || pstr[0] != null, Optional.empty(), browser.getDisplay());
286286
completion.Release();
287287
return phr[0];
288288
}
@@ -318,9 +318,8 @@ void releaseWebViews() {
318318
}
319319

320320
class WebViewProvider {
321-
322321
private CompletableFuture<WebViewWrapper> webViewWrapperFuture = wakeDisplayAfterFuture(new CompletableFuture<>());
323-
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});;
322+
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});
324323

325324
ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
326325
long[] ppv = new long[1];
@@ -333,7 +332,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
333332
webViewWrapper.webView_11 = initializeWebView_11(webView);
334333
webViewWrapper.webView_12 = initializeWebView_12(webView);
335334
webViewWrapper.webView_13 = initializeWebView_13(webView);
336-
webViewWrapperFuture.complete(webViewWrapper);
335+
boolean success = webViewWrapperFuture.complete(webViewWrapper);
336+
// Release the webViews if the webViewWrapperFuture has already timed out and completed exceptionally
337+
if(!success && webViewWrapperFuture.isCompletedExceptionally()) {
338+
webViewWrapper.releaseWebViews();
339+
return null;
340+
}
337341
return webView;
338342
}
339343

@@ -392,13 +396,13 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
392396

393397
private WebViewWrapper getWebViewWrapper(boolean waitForPendingWebviewTasksToFinish) {
394398
if(waitForPendingWebviewTasksToFinish) {
395-
processOSMessagesUntil(lastWebViewTask::isDone, browser.getDisplay());
399+
processOSMessagesUntil(lastWebViewTask::isDone, Optional.empty(), browser.getDisplay());
396400
}
397401
return webViewWrapperFuture.join();
398402
}
399403

400404
private WebViewWrapper getWebViewWrapper() {
401-
processOSMessagesUntil(webViewWrapperFuture::isDone, browser.getDisplay());
405+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
402406
return webViewWrapperFuture.join();
403407
}
404408

@@ -483,7 +487,7 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
483487
* events for initialization. Thus, this method does not implement an ordinary
484488
* readAndDispatch loop, but waits for an OS event to be processed.
485489
*/
486-
private static void processOSMessagesUntil(Supplier<Boolean> condition, Display display) {
490+
private static void processOSMessagesUntil(Supplier<Boolean> condition, Optional<Runnable> timeoutHandler, Display display) {
487491
MSG msg = new MSG();
488492
AtomicBoolean timeoutOccurred = new AtomicBoolean();
489493
// The timer call also wakes up the display to avoid being stuck in display.sleep()
@@ -496,10 +500,15 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Display
496500
}
497501
}
498502
if (!condition.get()) {
499-
SWT.error(SWT.ERROR_UNSPECIFIED, null, " Waiting for Edge operation to terminate timed out");
503+
timeoutHandler.ifPresent(Runnable::run);
504+
throw createTimeOutException();
500505
}
501506
}
502507

508+
private static SWTException createTimeOutException() {
509+
return new SWTException(SWT.ERROR_UNSPECIFIED, " Waiting for Edge operation to terminate timed out");
510+
}
511+
503512
static ICoreWebView2CookieManager getCookieManager() {
504513
WebViewEnvironment environmentWrapper = webViewEnvironments.get(Display.getCurrent());
505514
if (environmentWrapper == null) {
@@ -641,7 +650,10 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
641650
switch (result) {
642651
case COM.S_OK:
643652
new IUnknown(pv).AddRef();
644-
setupBrowser(result, pv);
653+
boolean success = setupBrowser(result, pv);
654+
if(!success) {
655+
initializationRollback.run();
656+
}
645657
break;
646658
case COM.E_WRONG_THREAD:
647659
initializationAbortion.run();
@@ -665,10 +677,13 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
665677
});
666678
}
667679

668-
void setupBrowser(int hr, long pv) {
680+
boolean setupBrowser(int hr, long pv) {
669681
long[] ppv = new long[] {pv};
670682
controller = new ICoreWebView2Controller(ppv[0]);
671683
final ICoreWebView2 webView = webViewProvider.initializeWebView(controller);
684+
if(webView == null) {
685+
return false;
686+
}
672687
webView.get_Settings(ppv);
673688
settings = new ICoreWebView2Settings(ppv[0]);
674689

@@ -768,6 +783,7 @@ void setupBrowser(int hr, long pv) {
768783
if (browser.isFocusControl()) {
769784
browserFocusIn(new Event());
770785
}
786+
return true;
771787
}
772788

773789
void browserDispose(Event event) {

0 commit comments

Comments
 (0)