@@ -264,7 +264,9 @@ 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 , exception -> {
268
+ throw exception ;
269
+ }, Display .getCurrent ());
268
270
completion .Release ();
269
271
return phr [0 ];
270
272
}
@@ -282,7 +284,9 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282
284
phr [0 ] = callable .applyAsInt (completion );
283
285
// "completion" callback may be called asynchronously,
284
286
// so keep processing next OS message that may call it
285
- processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || pstr [0 ] != null , browser .getDisplay ());
287
+ processOSMessagesUntil (() -> phr [0 ] != COM .S_OK || pstr [0 ] != null , exception -> {
288
+ throw exception ;
289
+ }, browser .getDisplay ());
286
290
completion .Release ();
287
291
return phr [0 ];
288
292
}
@@ -324,9 +328,8 @@ void releaseWebViews() {
324
328
}
325
329
326
330
class WebViewProvider {
327
-
328
331
private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
329
- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
332
+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
330
333
331
334
ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
332
335
long [] ppv = new long [1 ];
@@ -339,7 +342,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
339
342
webViewWrapper .webView_11 = initializeWebView_11 (webView );
340
343
webViewWrapper .webView_12 = initializeWebView_12 (webView );
341
344
webViewWrapper .webView_13 = initializeWebView_13 (webView );
342
- webViewWrapperFuture .complete (webViewWrapper );
345
+ boolean success = webViewWrapperFuture .complete (webViewWrapper );
346
+ // Release the webViews if the webViewWrapperFuture has already timed out and completed exceptionally
347
+ if (!success && webViewWrapperFuture .isCompletedExceptionally ()) {
348
+ webViewWrapper .releaseWebViews ();
349
+ return null ;
350
+ }
343
351
return webView ;
344
352
}
345
353
@@ -398,13 +406,19 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
398
406
399
407
private WebViewWrapper getWebViewWrapper (boolean waitForPendingWebviewTasksToFinish ) {
400
408
if (waitForPendingWebviewTasksToFinish ) {
401
- processOSMessagesUntil (lastWebViewTask ::isDone , browser .getDisplay ());
409
+ processOSMessagesUntil (lastWebViewTask ::isDone , exception -> {
410
+ lastWebViewTask .completeExceptionally (exception );
411
+ throw exception ;
412
+ }, browser .getDisplay ());
402
413
}
403
414
return webViewWrapperFuture .join ();
404
415
}
405
416
406
417
private WebViewWrapper getWebViewWrapper () {
407
- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
418
+ processOSMessagesUntil (webViewWrapperFuture ::isDone , exception -> {
419
+ webViewWrapperFuture .completeExceptionally (exception );
420
+ throw exception ;
421
+ }, browser .getDisplay ());
408
422
return webViewWrapperFuture .join ();
409
423
}
410
424
@@ -488,8 +502,9 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
488
502
* leads to a failure in browser initialization if processed in between the OS
489
503
* events for initialization. Thus, this method does not implement an ordinary
490
504
* readAndDispatch loop, but waits for an OS event to be processed.
505
+ * @throws Throwable
491
506
*/
492
- private static void processOSMessagesUntil (Supplier <Boolean > condition , Display display ) {
507
+ private static void processOSMessagesUntil (Supplier <Boolean > condition , Consumer < SWTException > timeoutHandler , Display display ) {
493
508
MSG msg = new MSG ();
494
509
AtomicBoolean timeoutOccurred = new AtomicBoolean ();
495
510
// The timer call also wakes up the display to avoid being stuck in display.sleep()
@@ -502,10 +517,14 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Display
502
517
}
503
518
}
504
519
if (!condition .get ()) {
505
- SWT . error ( SWT . ERROR_UNSPECIFIED , null , " Waiting for Edge operation to terminate timed out" );
520
+ timeoutHandler . accept ( createTimeOutException () );
506
521
}
507
522
}
508
523
524
+ private static SWTException createTimeOutException () {
525
+ return new SWTException (SWT .ERROR_UNSPECIFIED , "Waiting for Edge operation to terminate timed out" );
526
+ }
527
+
509
528
static ICoreWebView2CookieManager getCookieManager () {
510
529
WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
511
530
if (environmentWrapper == null ) {
@@ -622,16 +641,9 @@ private void createInstance(int previousAttempts) {
622
641
}
623
642
624
643
private IUnknown createControllerInitializationCallback (int previousAttempts ) {
625
- Runnable initializationRollback = () -> {
626
- if (environment2 != null ) {
627
- environment2 .Release ();
628
- environment2 = null ;
629
- }
630
- containingEnvironment .instances ().remove (this );
631
- };
632
644
Runnable initializationAbortion = () -> {
633
645
webViewProvider .abortInitialization ();
634
- initializationRollback . run ();
646
+ releaseEnvironment ();
635
647
};
636
648
return newCallback ((resultAsLong , pv ) -> {
637
649
int result = (int ) resultAsLong ;
@@ -657,7 +669,7 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
657
669
initializationAbortion .run ();
658
670
break ;
659
671
default :
660
- initializationRollback . run ();
672
+ releaseEnvironment ();
661
673
if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
662
674
System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
663
675
createInstance (previousAttempts + 1 );
@@ -671,10 +683,23 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
671
683
});
672
684
}
673
685
686
+ private void releaseEnvironment () {
687
+ if (environment2 != null ) {
688
+ environment2 .Release ();
689
+ environment2 = null ;
690
+ }
691
+ containingEnvironment .instances ().remove (this );
692
+ }
693
+
674
694
void setupBrowser (int hr , long pv ) {
675
695
long [] ppv = new long [] {pv };
676
696
controller = new ICoreWebView2Controller (ppv [0 ]);
677
697
final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
698
+ if (webView == null ) {
699
+ controller .Release ();
700
+ releaseEnvironment ();
701
+ return ;
702
+ }
678
703
webView .get_Settings (ppv );
679
704
settings = new ICoreWebView2Settings (ppv [0 ]);
680
705
0 commit comments