void (final boolean wait) { CompletableFuture<?> finishFuture = new CompletableFuture<>(); if (myShutdownFuture.compareAndSet(null, finishFuture)) { final List<Info> infos = new ArrayList<>(); synchronized (myProcMap) { for (Info o : myProcMap.values()) { if (o.handler != null) infos.add(o); } } if (infos.isEmpty()) { finishFuture.complete(null); return; } ApplicationManager.getApplication().executeOnPooledThread(() -> { try { destroyProcessesImpl(infos); if (wait) { for (Info o : infos) { o.handler.waitFor(); } } finishFuture.complete(null); } catch (Throwable e) { finishFuture.completeExceptionally(e); } }); } if (wait) { try { myShutdownFuture.get().get(); } catch (InterruptedException ignored) { } catch (java.util.concurrent.ExecutionException e) { LOG.warn(e); } } }