@@ -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}
@@ -298,29 +302,34 @@ class WebViewWrapper {
298302 void releaseWebViews () {
299303 if (webView != null ) {
300304 webView .Release ();
305+ webView = null ;
301306 }
302307 if (webView_2 != null ) {
303308 webView_2 .Release ();
309+ webView_2 = null ;
304310 }
305311 if (webView_10 != null ) {
306312 webView_10 .Release ();
313+ webView_10 = null ;
307314 }
308315 if (webView_11 != null ) {
309316 webView_11 .Release ();
317+ webView_11 = null ;
310318 }
311319 if (webView_12 != null ) {
312320 webView_12 .Release ();
321+ webView_12 = null ;
313322 }
314323 if (webView_13 != null ) {
315324 webView_13 .Release ();
325+ webView_13 = null ;
316326 }
317327 }
318328}
319329
320330class WebViewProvider {
321-
322331 private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
323- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
332+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
324333
325334 ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
326335 long [] ppv = new long [1 ];
@@ -333,7 +342,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
333342 webViewWrapper .webView_11 = initializeWebView_11 (webView );
334343 webViewWrapper .webView_12 = initializeWebView_12 (webView );
335344 webViewWrapper .webView_13 = initializeWebView_13 (webView );
336- 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+ }
337351 return webView ;
338352 }
339353
@@ -392,13 +406,19 @@ private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
392406
393407 private WebViewWrapper getWebViewWrapper (boolean waitForPendingWebviewTasksToFinish ) {
394408 if (waitForPendingWebviewTasksToFinish ) {
395- processOSMessagesUntil (lastWebViewTask ::isDone , browser .getDisplay ());
409+ processOSMessagesUntil (lastWebViewTask ::isDone , exception -> {
410+ lastWebViewTask .completeExceptionally (exception );
411+ throw exception ;
412+ }, browser .getDisplay ());
396413 }
397414 return webViewWrapperFuture .join ();
398415 }
399416
400417 private WebViewWrapper getWebViewWrapper () {
401- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
418+ processOSMessagesUntil (webViewWrapperFuture ::isDone , exception -> {
419+ webViewWrapperFuture .completeExceptionally (exception );
420+ throw exception ;
421+ }, browser .getDisplay ());
402422 return webViewWrapperFuture .join ();
403423 }
404424
@@ -482,8 +502,9 @@ private <T> CompletableFuture<T> wakeDisplayAfterFuture(CompletableFuture<T> fut
482502 * leads to a failure in browser initialization if processed in between the OS
483503 * events for initialization. Thus, this method does not implement an ordinary
484504 * readAndDispatch loop, but waits for an OS event to be processed.
505+ * @throws Throwable
485506 */
486- private static void processOSMessagesUntil (Supplier <Boolean > condition , Display display ) {
507+ private static void processOSMessagesUntil (Supplier <Boolean > condition , Consumer < SWTException > timeoutHandler , Display display ) {
487508 MSG msg = new MSG ();
488509 AtomicBoolean timeoutOccurred = new AtomicBoolean ();
489510 // The timer call also wakes up the display to avoid being stuck in display.sleep()
@@ -496,10 +517,14 @@ private static void processOSMessagesUntil(Supplier<Boolean> condition, Display
496517 }
497518 }
498519 if (!condition .get ()) {
499- SWT . error ( SWT . ERROR_UNSPECIFIED , null , " Waiting for Edge operation to terminate timed out" );
520+ timeoutHandler . accept ( createTimeOutException () );
500521 }
501522}
502523
524+ private static SWTException createTimeOutException () {
525+ return new SWTException (SWT .ERROR_UNSPECIFIED , "Waiting for Edge operation to terminate timed out" );
526+ }
527+
503528static ICoreWebView2CookieManager getCookieManager () {
504529 WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
505530 if (environmentWrapper == null ) {
@@ -616,16 +641,9 @@ private void createInstance(int previousAttempts) {
616641}
617642
618643private IUnknown createControllerInitializationCallback (int previousAttempts ) {
619- Runnable initializationRollback = () -> {
620- if (environment2 != null ) {
621- environment2 .Release ();
622- environment2 = null ;
623- }
624- containingEnvironment .instances ().remove (this );
625- };
626644 Runnable initializationAbortion = () -> {
627645 webViewProvider .abortInitialization ();
628- initializationRollback . run ();
646+ releaseEnvironment ();
629647 };
630648 return newCallback ((resultAsLong , pv ) -> {
631649 int result = (int ) resultAsLong ;
@@ -651,7 +669,7 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
651669 initializationAbortion .run ();
652670 break ;
653671 default :
654- initializationRollback . run ();
672+ releaseEnvironment ();
655673 if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
656674 System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
657675 createInstance (previousAttempts + 1 );
@@ -665,10 +683,23 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
665683 });
666684}
667685
686+ private void releaseEnvironment () {
687+ if (environment2 != null ) {
688+ environment2 .Release ();
689+ environment2 = null ;
690+ }
691+ containingEnvironment .instances ().remove (this );
692+ }
693+
668694void setupBrowser (int hr , long pv ) {
669695 long [] ppv = new long [] {pv };
670696 controller = new ICoreWebView2Controller (ppv [0 ]);
671697 final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
698+ if (webView == null ) {
699+ controller .Release ();
700+ releaseEnvironment ();
701+ return ;
702+ }
672703 webView .get_Settings (ppv );
673704 settings = new ICoreWebView2Settings (ppv [0 ]);
674705
0 commit comments