Skip to content

Commit 33e761b

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 3ecc39c commit 33e761b

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

+28-12
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
}
@@ -317,9 +317,8 @@ void releaseWebViews() {
317317
}
318318

319319
class WebViewProvider {
320-
321320
private CompletableFuture<WebViewWrapper> webViewWrapperFuture = wakeDisplayAfterFuture(new CompletableFuture<>());
322-
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});;
321+
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});
323322

324323
ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
325324
long[] ppv = new long[1];
@@ -332,7 +331,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
332331
webViewWrapper.webView_11 = initializeWebView_11(webView);
333332
webViewWrapper.webView_12 = initializeWebView_12(webView);
334333
webViewWrapper.webView_13 = initializeWebView_13(webView);
335-
webViewWrapperFuture.complete(webViewWrapper);
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+
}
336340
return webView;
337341
}
338342

@@ -341,7 +345,7 @@ private void abortInitialization() {
341345
}
342346

343347
void releaseWebView() {
344-
processOSMessagesUntil(webViewWrapperFuture::isDone, browser.getDisplay());
348+
processOSMessagesUntil(webViewWrapperFuture::isDone, Optional.of(() -> webViewWrapperFuture.completeExceptionally(createTimeOutException())), browser.getDisplay());
345349
webViewWrapperFuture.join().releaseWebViews();
346350
}
347351

@@ -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(handler -> handler.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) {
@@ -640,7 +649,10 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
640649
switch ((int) result) {
641650
case COM.S_OK:
642651
new IUnknown(pv).AddRef();
643-
setupBrowser((int) result, pv);
652+
boolean success = setupBrowser((int) result, pv);
653+
if(!success) {
654+
initializationRollback.run();
655+
}
644656
break;
645657
case COM.E_WRONG_THREAD:
646658
initializationAbortion.run();
@@ -664,10 +676,13 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
664676
});
665677
}
666678

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

@@ -767,6 +782,7 @@ void setupBrowser(int hr, long pv) {
767782
if (browser.isFocusControl()) {
768783
browserFocusIn(new Event());
769784
}
785+
return true;
770786
}
771787

772788
void browserDispose(Event event) {

0 commit comments

Comments
 (0)