@@ -264,7 +264,7 @@ 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 , Function :: identity , Display .getCurrent ());
268268 completion .Release ();
269269 return phr [0 ];
270270}
@@ -282,7 +282,7 @@ int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
282282 phr [0 ] = callable .applyAsInt (completion );
283283 // "completion" callback may be called asynchronously,
284284 // 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 ());
286286 completion .Release ();
287287 return phr [0 ];
288288}
@@ -318,9 +318,8 @@ void releaseWebViews() {
318318}
319319
320320class WebViewProvider {
321-
322321 private CompletableFuture <WebViewWrapper > webViewWrapperFuture = wakeDisplayAfterFuture (new CompletableFuture <>());
323- private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});;
322+ private CompletableFuture <Void > lastWebViewTask = webViewWrapperFuture .thenRun (() -> {});
324323
325324 ICoreWebView2 initializeWebView (ICoreWebView2Controller controller ) {
326325 long [] ppv = new long [1 ];
@@ -333,7 +332,12 @@ ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
333332 webViewWrapper .webView_11 = initializeWebView_11 (webView );
334333 webViewWrapper .webView_12 = initializeWebView_12 (webView );
335334 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+ }
337341 return webView ;
338342 }
339343
@@ -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 , () -> lastWebViewTask . completeExceptionally ( createTimeOutException ()), browser .getDisplay ());
396400 }
397401 return webViewWrapperFuture .join ();
398402 }
399403
400404 private WebViewWrapper getWebViewWrapper () {
401- processOSMessagesUntil (webViewWrapperFuture ::isDone , browser .getDisplay ());
405+ processOSMessagesUntil (webViewWrapperFuture ::isDone , () -> 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 , 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 .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+
503512static ICoreWebView2CookieManager getCookieManager () {
504513 WebViewEnvironment environmentWrapper = webViewEnvironments .get (Display .getCurrent ());
505514 if (environmentWrapper == null ) {
@@ -616,16 +625,9 @@ private void createInstance(int previousAttempts) {
616625}
617626
618627private IUnknown createControllerInitializationCallback (int previousAttempts ) {
619- Runnable initializationRollback = () -> {
620- if (environment2 != null ) {
621- environment2 .Release ();
622- environment2 = null ;
623- }
624- containingEnvironment .instances ().remove (this );
625- };
626628 Runnable initializationAbortion = () -> {
627629 webViewProvider .abortInitialization ();
628- initializationRollback . run ();
630+ releaseEnvironment ();
629631 };
630632 return newCallback ((resultAsLong , pv ) -> {
631633 int result = (int ) resultAsLong ;
@@ -651,7 +653,7 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
651653 initializationAbortion .run ();
652654 break ;
653655 default :
654- initializationRollback . run ();
656+ releaseEnvironment ();
655657 if (previousAttempts < MAXIMUM_CREATION_RETRIES ) {
656658 System .err .println (String .format ("Edge initialization failed, retrying (attempt %d / %d)" , previousAttempts + 1 , MAXIMUM_CREATION_RETRIES ));
657659 createInstance (previousAttempts + 1 );
@@ -665,10 +667,23 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
665667 });
666668}
667669
670+ private void releaseEnvironment () {
671+ if (environment2 != null ) {
672+ environment2 .Release ();
673+ environment2 = null ;
674+ }
675+ containingEnvironment .instances ().remove (this );
676+ }
677+
668678void setupBrowser (int hr , long pv ) {
669679 long [] ppv = new long [] {pv };
670680 controller = new ICoreWebView2Controller (ppv [0 ]);
671681 final ICoreWebView2 webView = webViewProvider .initializeWebView (controller );
682+ if (webView == null ) {
683+ controller .Release ();
684+ releaseEnvironment ();
685+ return ;
686+ }
672687 webView .get_Settings (ppv );
673688 settings = new ICoreWebView2Settings (ppv [0 ]);
674689
0 commit comments