Skip to content

Commit 8b86b9b

Browse files
committed
WIP: Edge Browser Scheduled Job timeout
1 parent 60ef7e9 commit 8b86b9b

File tree

2 files changed

+82
-65
lines changed

2 files changed

+82
-65
lines changed

bundles/org.eclipse.swt/Eclipse SWT Browser/win32/org/eclipse/swt/browser/Edge.java

Lines changed: 81 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -287,149 +287,161 @@ static int callAndWait(String[] pstr, ToIntFunction<IUnknown> callable) {
287287
return phr[0];
288288
}
289289

290-
class WebViewProvider {
290+
class WebViewWrapper {
291+
private ICoreWebView2 webView;
292+
private ICoreWebView2_2 webView_2;
293+
private ICoreWebView2_10 webView_10;
294+
private ICoreWebView2_11 webView_11;
295+
private ICoreWebView2_12 webView_12;
296+
private ICoreWebView2_13 webView_13;
297+
}
291298

292-
private CompletableFuture<ICoreWebView2> webViewFuture = new CompletableFuture<>();
293-
private CompletableFuture<ICoreWebView2_2> webView_2Future = new CompletableFuture<>();
294-
private CompletableFuture<ICoreWebView2_10> webView_10Future = new CompletableFuture<>();
295-
private CompletableFuture<ICoreWebView2_11> webView_11Future = new CompletableFuture<>();
296-
private CompletableFuture<ICoreWebView2_12> webView_12Future = new CompletableFuture<>();
297-
private CompletableFuture<ICoreWebView2_13> webView_13Future = new CompletableFuture<>();
299+
class WebViewProvider {
298300

299-
private CompletableFuture<Void> lastWebViewTask = webViewFuture.thenRun(() -> {});
301+
private CompletableFuture<WebViewWrapper> webViewWrapperFuture = initializeWebViewFutureWithTimeOut();
302+
private CompletableFuture<Void> lastWebViewTask = webViewWrapperFuture.thenRun(() -> {});;
300303

301304
ICoreWebView2 initializeWebView(ICoreWebView2Controller controller) {
302305
long[] ppv = new long[1];
303306
controller.get_CoreWebView2(ppv);
304307
final ICoreWebView2 webView = new ICoreWebView2(ppv[0]);
305-
initializeWebView_2(webView);
306-
initializeWebView_10(webView);
307-
initializeWebView_11(webView);
308-
initializeWebView_12(webView);
309-
initializeWebView_13(webView);
310-
webViewFuture.complete(webView);
308+
final WebViewWrapper webViewWrapper = new WebViewWrapper();
309+
webViewWrapper.webView = webView;
310+
webViewWrapper.webView_2 = initializeWebView_2(webView);
311+
webViewWrapper.webView_10 = initializeWebView_10(webView);
312+
webViewWrapper.webView_11 = initializeWebView_11(webView);
313+
webViewWrapper.webView_12 = initializeWebView_12(webView);
314+
webViewWrapper.webView_13= initializeWebView_13(webView);
315+
webViewWrapperFuture.complete(webViewWrapper);
311316
return webView;
312317
}
313318

319+
private CompletableFuture<WebViewWrapper> initializeWebViewFutureWithTimeOut() {
320+
CompletableFuture<WebViewWrapper> webViewWrapperFuture = new CompletableFuture<>();
321+
webViewWrapperFuture.orTimeout(3, TimeUnit.MILLISECONDS).exceptionally(exception -> {
322+
releaseEnvironment();
323+
// Throw exception on the Display thread directly to prevent CompletableFuture
324+
// to wrap the exception and throw it silently
325+
browser.getDisplay().execute(() -> SWT.error(SWT.ERROR_UNSPECIFIED, exception, "Edge Browser initialization timed out"));
326+
return null;
327+
});
328+
return webViewWrapperFuture;
329+
}
330+
314331
private void abortInitialization() {
315-
webViewFuture.cancel(true);
332+
webViewWrapperFuture.cancel(true);
316333
}
317334

318-
private void initializeWebView_2(ICoreWebView2 webView) {
335+
private ICoreWebView2_2 initializeWebView_2(ICoreWebView2 webView) {
319336
long[] ppv = new long[1];
320337
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_2, ppv);
321338
if (hr == COM.S_OK) {
322-
webView_2Future.complete(new ICoreWebView2_2(ppv[0]));
323-
} else {
324-
webView_2Future.cancel(true);
339+
return new ICoreWebView2_2(ppv[0]);
325340
}
341+
return null;
326342
}
327343

328-
private void initializeWebView_10(ICoreWebView2 webView) {
344+
private ICoreWebView2_10 initializeWebView_10(ICoreWebView2 webView) {
329345
long[] ppv = new long[1];
330346
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_10, ppv);
331347
if (hr == COM.S_OK) {
332-
webView_10Future.complete(new ICoreWebView2_10(ppv[0]));
333-
} else {
334-
webView_10Future.cancel(true);
348+
return new ICoreWebView2_10(ppv[0]);
335349
}
350+
return null;
336351
}
337352

338-
private void initializeWebView_11(ICoreWebView2 webView) {
353+
private ICoreWebView2_11 initializeWebView_11(ICoreWebView2 webView) {
339354
long[] ppv = new long[1];
340355
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_11, ppv);
341356
if (hr == COM.S_OK) {
342-
webView_11Future.complete(new ICoreWebView2_11(ppv[0]));
343-
} else {
344-
webView_11Future.cancel(true);
357+
return new ICoreWebView2_11(ppv[0]);
345358
}
359+
return null;
346360
}
347361

348-
private void initializeWebView_12(ICoreWebView2 webView) {
362+
private ICoreWebView2_12 initializeWebView_12(ICoreWebView2 webView) {
349363
long[] ppv = new long[1];
350364
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_12, ppv);
351365
if (hr == COM.S_OK) {
352-
webView_12Future.complete(new ICoreWebView2_12(ppv[0]));
353-
} else {
354-
webView_12Future.cancel(true);
366+
return new ICoreWebView2_12(ppv[0]);
355367
}
368+
return null;
356369
}
357370

358-
private void initializeWebView_13(ICoreWebView2 webView) {
371+
private ICoreWebView2_13 initializeWebView_13(ICoreWebView2 webView) {
359372
long[] ppv = new long[1];
360373
int hr = webView.QueryInterface(COM.IID_ICoreWebView2_13, ppv);
361374
if (hr == COM.S_OK) {
362-
webView_13Future.complete(new ICoreWebView2_13(ppv[0]));
363-
} else {
364-
webView_13Future.cancel(true);
375+
return new ICoreWebView2_13(ppv[0]);
365376
}
377+
return null;
366378
}
367379

368380
ICoreWebView2 getWebView(boolean waitForPendingWebviewTasksToFinish) {
369381
if(waitForPendingWebviewTasksToFinish) {
370382
waitForFutureToFinish(lastWebViewTask);
371383
}
372-
return webViewFuture.join();
384+
return webViewWrapperFuture.join().webView;
373385
}
374386

375387
ICoreWebView2_2 getWebView_2(boolean waitForPendingWebviewTasksToFinish) {
376388
if(waitForPendingWebviewTasksToFinish) {
377389
waitForFutureToFinish(lastWebViewTask);
378390
}
379-
return webView_2Future.join();
391+
return webViewWrapperFuture.join().webView_2;
380392
}
381393

382394
boolean isWebView_2Available() {
383-
waitForFutureToFinish(webView_2Future);
384-
return !webView_2Future.isCancelled();
395+
waitForFutureToFinish(webViewWrapperFuture);
396+
return webViewWrapperFuture.join().webView_2 != null;
385397
}
386398

387399
ICoreWebView2_10 getWebView_10(boolean waitForPendingWebviewTasksToFinish) {
388400
if(waitForPendingWebviewTasksToFinish) {
389401
waitForFutureToFinish(lastWebViewTask);
390402
}
391-
return webView_10Future.join();
403+
return webViewWrapperFuture.join().webView_10;
392404
}
393405

394406
boolean isWebView_10Available() {
395-
waitForFutureToFinish(webView_10Future);
396-
return !webView_10Future.isCancelled();
407+
waitForFutureToFinish(webViewWrapperFuture);
408+
return webViewWrapperFuture.join().webView_10 != null;
397409
}
398410

399411
ICoreWebView2_11 getWebView_11(boolean waitForPendingWebviewTasksToFinish) {
400412
if(waitForPendingWebviewTasksToFinish) {
401413
waitForFutureToFinish(lastWebViewTask);
402414
}
403-
return webView_11Future.join();
415+
return webViewWrapperFuture.join().webView_11;
404416
}
405417

406418
boolean isWebView_11Available() {
407-
waitForFutureToFinish(webView_11Future);
408-
return !webView_11Future.isCancelled();
419+
waitForFutureToFinish(webViewWrapperFuture);
420+
return webViewWrapperFuture.join().webView_11 != null;
409421
}
410422

411423
ICoreWebView2_12 getWebView_12(boolean waitForPendingWebviewTasksToFinish) {
412424
if(waitForPendingWebviewTasksToFinish) {
413425
waitForFutureToFinish(lastWebViewTask);
414426
}
415-
return webView_12Future.join();
427+
return webViewWrapperFuture.join().webView_12;
416428
}
417429

418430
boolean isWebView_12Available() {
419-
waitForFutureToFinish(webView_12Future);
420-
return !webView_12Future.isCancelled();
431+
waitForFutureToFinish(webViewWrapperFuture);
432+
return webViewWrapperFuture.join().webView_12 != null;
421433
}
422434

423435
ICoreWebView2_13 getWebView_13(boolean waitForPendingWebviewTasksToFinish) {
424436
if(waitForPendingWebviewTasksToFinish) {
425437
waitForFutureToFinish(lastWebViewTask);
426438
}
427-
return webView_13Future.join();
439+
return webViewWrapperFuture.join().webView_13;
428440
}
429441

430442
boolean isWebView_13Available() {
431-
waitForFutureToFinish(webView_13Future);
432-
return !webView_13Future.isCancelled();
443+
waitForFutureToFinish(webViewWrapperFuture);
444+
return webViewWrapperFuture.join().webView_13 != null;
433445
}
434446

435447
/*
@@ -587,21 +599,13 @@ private void createInstance(int previousAttempts) {
587599
}
588600

589601
private IUnknown createControllerInitializationCallback(int previousAttempts) {
590-
Runnable initializationRollback = () -> {
591-
webViewProvider.abortInitialization();
592-
if (environment2 != null) {
593-
environment2.Release();
594-
environment2 = null;
595-
}
596-
containingEnvironment.instances().remove(this);
597-
};
598602
return newCallback((result, pv) -> {
599603
if (browser.isDisposed()) {
600-
initializationRollback.run();
604+
rollbackInitialization();
601605
return COM.S_OK;
602606
}
603607
if (result == OS.HRESULT_FROM_WIN32(OS.ERROR_INVALID_STATE)) {
604-
initializationRollback.run();
608+
rollbackInitialization();
605609
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null,
606610
" Edge instance with same data folder but different environment options already exists");
607611
}
@@ -611,14 +615,14 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
611615
setupBrowser((int) result, pv);
612616
break;
613617
case COM.E_WRONG_THREAD:
614-
initializationRollback.run();
618+
rollbackInitialization();
615619
error(SWT.ERROR_THREAD_INVALID_ACCESS, (int) result);
616620
break;
617621
case COM.E_ABORT:
618-
initializationRollback.run();
622+
rollbackInitialization();
619623
break;
620624
default:
621-
initializationRollback.run();
625+
rollbackInitialization();
622626
if (previousAttempts < MAXIMUM_CREATION_RETRIES) {
623627
System.err.println(String.format("Edge initialization failed, retrying (attempt %d / %d)", previousAttempts + 1, MAXIMUM_CREATION_RETRIES));
624628
createInstance(previousAttempts + 1);
@@ -632,6 +636,19 @@ private IUnknown createControllerInitializationCallback(int previousAttempts) {
632636
});
633637
}
634638

639+
private void rollbackInitialization() {
640+
webViewProvider.abortInitialization();
641+
releaseEnvironment();
642+
}
643+
644+
private void releaseEnvironment() {
645+
if (environment2 != null) {
646+
environment2.Release();
647+
environment2 = null;
648+
}
649+
containingEnvironment.instances().remove(this);
650+
}
651+
635652
void setupBrowser(int hr, long pv) {
636653
long[] ppv = new long[] {pv};
637654
controller = new ICoreWebView2Controller(ppv[0]);

tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_browser_Browser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ private int reportOpenedDescriptors() {
302302
}
303303

304304
private Browser createBrowser(Shell s, int flags) {
305-
long maximumBrowserCreationMilliseconds = 90_000;
305+
long maximumBrowserCreationMilliseconds = 10_000;
306306
long createStartTime = System.currentTimeMillis();
307307
Browser b = new Browser(s, flags);
308308
// Wait for asynchronous initialization via getting URL

0 commit comments

Comments
 (0)