Skip to content

Commit 2778cf5

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 # Conflicts: # bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java
1 parent 4e12df1 commit 2778cf5

File tree

1 file changed

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

1 file changed

+28
-12
lines changed

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

Lines changed: 28 additions & 12 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

@@ -342,7 +346,7 @@ private void abortInitialization() {
342346
}
343347

344348
void releaseWebView() {
345-
processOSMessagesUntil(webViewWrapperFuture::isDone, browser.getDisplay());
349+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
346350
webViewWrapperFuture.join().releaseWebViews();
347351
}
348352

@@ -393,13 +397,13 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
393397

394398
private WebViewWrapper getWebViewWrapper(boolean waitForPendingWebviewTasksToFinish) {
395399
if(waitForPendingWebviewTasksToFinish) {
396-
processOSMessagesUntil(lastWebViewTask::isDone, browser.getDisplay());
400+
processOSMessagesUntil(lastWebViewTask::isDone, Optional.empty(), browser.getDisplay());
397401
}
398402
return webViewWrapperFuture.join();
399403
}
400404

401405
private WebViewWrapper getWebViewWrapper() {
402-
processOSMessagesUntil(webViewWrapperFuture::isDone, browser.getDisplay());
406+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
403407
return webViewWrapperFuture.join();
404408
}
405409

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

509+
private static SWTException createTimeOutException() {
510+
return new SWTException(SWT.ERROR_UNSPECIFIED, " Waiting for Edge operation to terminate timed out");
511+
}
512+
504513
static ICoreWebView2CookieManager getCookieManager() {
505514
WebViewEnvironment environmentWrapper = webViewEnvironments.get(Display.getCurrent());
506515
if (environmentWrapper == null) {
@@ -642,7 +651,10 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
642651
switch (result) {
643652
case COM.S_OK:
644653
new IUnknown(pv).AddRef();
645-
setupBrowser(result, pv);
654+
boolean success = setupBrowser(result, pv);
655+
if(!success) {
656+
initializationRollback.run();
657+
}
646658
break;
647659
case COM.E_WRONG_THREAD:
648660
initializationAbortion.run();
@@ -666,10 +678,13 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
666678
});
667679
}
668680

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

@@ -769,6 +784,7 @@ void setupBrowser(int hr, long pv) {
769784
if (browser.isFocusControl()) {
770785
browserFocusIn(new Event());
771786
}
787+
return true;
772788
}
773789

774790
void browserDispose(Event event) {

0 commit comments

Comments
 (0)