@@ -264,7 +264,9 @@ 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 , exception -> {
268+ throw exception ;
269+ }, Display .getCurrent ());
268270 completion .Release ();
269271 return phr [0 ];
270272}
@@ -282,7 +284,9 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282284 phr [0 ] = callable .applyAsInt (completion );
283285 // "completion" callback may be called asynchronously,
284286 // 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 ());
286290 completion .Release ();
287291 return phr [0 ];
288292}
@@ -324,9 +328,8 @@ void releaseWebViews() {
324328}
325329
326330class WebViewProvider {
327-
328331 private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
329- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
332+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
330333
331334 ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
332335 long [] ppv = new long [1 ];
@@ -339,7 +342,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
339342 webViewWrapper .webView_11 = initializeWebView_11 (webView );
340343 webViewWrapper .webView_12 = initializeWebView_12 (webView );
341344 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+ }
343351 return webView ;
344352 }
345353
@@ -398,13 +406,19 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
398406
399407 private WebViewWrapper getWebViewWrapper (boolean waitForPendingWebviewTasksToFinish ) {
400408 if (waitForPendingWebviewTasksToFinish ) {
401- processOSMessagesUntil (lastWebViewTask ::isDone , browser .getDisplay ());
409+ processOSMessagesUntil (lastWebViewTask ::isDone , exception -> {
410+ lastWebViewTask .completeExceptionally (exception );
411+ throw exception ;
412+ }, browser .getDisplay ());
402413 }
403414 return webViewWrapperFuture .join ();
404415 }
405416
406417 private WebViewWrapper getWebViewWrapper () {
407- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
418+ processOSMessagesUntil (webViewWrapperFuture ::isDone , exception -> {
419+ webViewWrapperFuture .completeExceptionally (exception );
420+ throw exception ;
421+ }, browser .getDisplay ());
408422 return webViewWrapperFuture .join ();
409423 }
410424
@@ -488,8 +502,9 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
488502 * leads to a failure in browser initialization if processed in between the OS
489503 * events for initialization. Thus, this method does not implement an ordinary
490504 * readAndDispatch loop, but waits for an OS event to be processed.
505+ * @throws Throwable
491506 */
492- private static void processOSMessagesUntil (Supplier <Boolean > condition , Display display ) {
507+ private static void processOSMessagesUntil (Supplier <Boolean > condition , Consumer < SWTException > timeoutHandler , Display display ) {
493508 MSG msg = new MSG ();
494509 AtomicBoolean timeoutOccurred = new AtomicBoolean ();
495510 // 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
502517 }
503518 }
504519 if (!condition .get ()) {
505- SWT . error ( SWT . ERROR_UNSPECIFIED , null , " Waiting for Edge operation to terminate timed out" );
520+ timeoutHandler . accept ( createTimeOutException () );
506521 }
507522}
508523
524+ private static SWTException createTimeOutException () {
525+ return new SWTException (SWT .ERROR_UNSPECIFIED , "Waiting for Edge operation to terminate timed out" );
526+ }
527+
509528static ICoreWebView2CookieManager getCookieManager () {
510529 WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
511530 if (environmentWrapper == null ) {
@@ -622,16 +641,9 @@ private void createInstance(int previousAttempts) {
622641}
623642
624643private IUnknown createControllerInitializationCallback (int previousAttempts ) {
625- Runnable initializationRollback = () -> {
626- if (environment2 != null ) {
627- environment2 .Release ();
628- environment2 = null ;
629- }
630- containingEnvironment .instances ().remove (this );
631- };
632644 Runnable initializationAbortion = () -> {
633645 webViewProvider .abortInitialization ();
634- initializationRollback . run ();
646+ releaseEnvironment ();
635647 };
636648 return newCallback ((resultAsLong , pv ) -> {
637649 int result = (int ) resultAsLong ;
@@ -657,7 +669,7 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
657669 initializationAbortion .run ();
658670 break ;
659671 default :
660- initializationRollback . run ();
672+ releaseEnvironment ();
661673 if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
662674 System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
663675 createInstance (previousAttempts + 1 );
@@ -671,10 +683,23 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
671683 });
672684}
673685
686+ private void releaseEnvironment () {
687+ if (environment2 != null ) {
688+ environment2 .Release ();
689+ environment2 = null ;
690+ }
691+ containingEnvironment .instances ().remove (this );
692+ }
693+
674694void setupBrowser (int hr , long pv ) {
675695 long [] ppv = new long [] {pv };
676696 controller = new ICoreWebView2Controller (ppv [0 ]);
677697 final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
698+ if (webView == null ) {
699+ controller .Release ();
700+ releaseEnvironment ();
701+ return ;
702+ }
678703 webView .get_Settings (ppv );
679704 settings = new ICoreWebView2Settings (ppv [0 ]);
680705
0 commit comments