@@ -264,7 +264,7 @@ static int callAndWait(long[] ppv, ToIntFunction<IUnknown> callable) {
264
264
phr [0 ] = callable .applyAsInt (completion );
265
265
// "completion" callback may be called asynchronously,
266
266
// 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 , Function :: identity , Display .getCurrent ());
268
268
completion .Release ();
269
269
return phr [0 ];
270
270
}
@@ -282,7 +282,7 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282
282
phr [0 ] = callable .applyAsInt (completion );
283
283
// "completion" callback may be called asynchronously,
284
284
// 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 , Function :: identity , browser .getDisplay ());
286
286
completion .Release ();
287
287
return phr [0 ];
288
288
}
@@ -318,9 +318,8 @@ void releaseWebViews() {
318
318
}
319
319
320
320
class WebViewProvider {
321
-
322
321
private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
323
- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
322
+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
324
323
325
324
ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
326
325
long [] ppv = new long [1 ];
@@ -333,7 +332,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
333
332
webViewWrapper .webView_11 = initializeWebView_11 (webView );
334
333
webViewWrapper .webView_12 = initializeWebView_12 (webView );
335
334
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
+ }
337
341
return webView ;
338
342
}
339
343
@@ -392,13 +396,13 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
392
396
393
397
private WebViewWrapper getWebViewWrapper (boolean waitForPendingWebviewTasksToFinish ) {
394
398
if (waitForPendingWebviewTasksToFinish ) {
395
- processOSMessagesUntil (lastWebViewTask ::isDone , browser .getDisplay ());
399
+ processOSMessagesUntil (lastWebViewTask ::isDone , Function :: identity , browser .getDisplay ());
396
400
}
397
401
return webViewWrapperFuture .join ();
398
402
}
399
403
400
404
private WebViewWrapper getWebViewWrapper () {
401
- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
405
+ processOSMessagesUntil (webViewWrapperFuture ::isDone , () -> webViewWrapperFuture . completeExceptionally ( createTimeOutException ()), browser .getDisplay ());
402
406
return webViewWrapperFuture .join ();
403
407
}
404
408
@@ -483,7 +487,7 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
483
487
* events for initialization. Thus, this method does not implement an ordinary
484
488
* readAndDispatch loop, but waits for an OS event to be processed.
485
489
*/
486
- private static void processOSMessagesUntil (Supplier <Boolean > condition , Display display ) {
490
+ private static void processOSMessagesUntil (Supplier <Boolean > condition , Runnable timeoutHandler , Display display ) {
487
491
MSG msg = new MSG ();
488
492
AtomicBoolean timeoutOccurred = new AtomicBoolean ();
489
493
// 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
496
500
}
497
501
}
498
502
if (!condition .get ()) {
499
- SWT .error (SWT .ERROR_UNSPECIFIED , null , " Waiting for Edge operation to terminate timed out" );
503
+ timeoutHandler .run ();
504
+ throw createTimeOutException ();
500
505
}
501
506
}
502
507
508
+ private static SWTException createTimeOutException () {
509
+ return new SWTException (SWT .ERROR_UNSPECIFIED , " Waiting for Edge operation to terminate timed out" );
510
+ }
511
+
503
512
static ICoreWebView2CookieManager getCookieManager () {
504
513
WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
505
514
if (environmentWrapper == null ) {
@@ -616,16 +625,9 @@ private void createInstance(int previousAttempts) {
616
625
}
617
626
618
627
private IUnknown createControllerInitializationCallback (int previousAttempts ) {
619
- Runnable initializationRollback = () -> {
620
- if (environment2 != null ) {
621
- environment2 .Release ();
622
- environment2 = null ;
623
- }
624
- containingEnvironment .instances ().remove (this );
625
- };
626
628
Runnable initializationAbortion = () -> {
627
629
webViewProvider .abortInitialization ();
628
- initializationRollback . run ();
630
+ releaseEnvironment ();
629
631
};
630
632
return newCallback ((resultAsLong , pv ) -> {
631
633
int result = (int ) resultAsLong ;
@@ -651,7 +653,7 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
651
653
initializationAbortion .run ();
652
654
break ;
653
655
default :
654
- initializationRollback . run ();
656
+ releaseEnvironment ();
655
657
if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
656
658
System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
657
659
createInstance (previousAttempts + 1 );
@@ -665,10 +667,23 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
665
667
});
666
668
}
667
669
670
+ private void releaseEnvironment () {
671
+ if (environment2 != null ) {
672
+ environment2 .Release ();
673
+ environment2 = null ;
674
+ }
675
+ containingEnvironment .instances ().remove (this );
676
+ }
677
+
668
678
void setupBrowser (int hr , long pv ) {
669
679
long [] ppv = new long [] {pv };
670
680
controller = new ICoreWebView2Controller (ppv [0 ]);
671
681
final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
682
+ if (webView == null ) {
683
+ controller .Release ();
684
+ releaseEnvironment ();
685
+ return ;
686
+ }
672
687
webView .get_Settings (ppv );
673
688
settings = new ICoreWebView2Settings (ppv [0 ]);
674
689
0 commit comments