void (@Nullable Runnable runAfterUpdate) { if (!myIsUpdating.compareAndSet(false, true)) return; updateBranchesWithIncoming(false); updateBranchesWithOutgoing(); new Task.Backgroundable(myProject, GitBundle.message("branches.update.info.process")) { @Override public void run(@NotNull ProgressIndicator indicator) { Semaphore semaphore = new Semaphore(0); //to avoid eating events and make semaphore being released we use 'this' here instead of "update" myQueue.queue(Update.create(this, () -> semaphore.release())); myQueue.flush(); try { while (true) { if (indicator.isCanceled()) break; if (semaphore.tryAcquire(100, TimeUnit.MILLISECONDS)) break; } } catch (InterruptedException e) { throw new ProcessCanceledException(e); } } @Override public void onFinished() { myIsUpdating.set(false); if (runAfterUpdate != null) { runAfterUpdate.run(); } } }.queue(); }