private void startBackgroundProcess( @NotNull final DumbModeTask task, @NotNull final ProgressIndicatorEx indicator) { ProgressManager.getInstance() .run( new Task.Backgroundable(myProject, IdeBundle.message("progress.indexing"), false) { @Override public void run(@NotNull final ProgressIndicator visibleIndicator) { if (ApplicationManager.getApplication().isInternal()) LOG.info("Running dumb mode task: " + task); final ShutDownTracker shutdownTracker = ShutDownTracker.getInstance(); final Thread self = Thread.currentThread(); try { HeavyProcessLatch.INSTANCE.processStarted(); shutdownTracker.registerStopperThread(self); indicator.checkCanceled(); if (visibleIndicator instanceof ProgressIndicatorEx) { indicator.addStateDelegate((ProgressIndicatorEx) visibleIndicator); ((ProgressIndicatorEx) visibleIndicator) .addStateDelegate(new AppIconProgress()); } indicator.setIndeterminate(true); indicator.setText(IdeBundle.message("progress.indexing.scanning")); task.performInDumbMode(indicator); } catch (ProcessCanceledException ignored) { } catch (Throwable unexpected) { LOG.error(unexpected); } finally { shutdownTracker.unregisterStopperThread(self); HeavyProcessLatch.INSTANCE.processFinished(); taskFinished(task); } } }); }
private void scheduleCacheUpdate(@NotNull final DumbModeTask task, boolean forceDumbMode) { if (ApplicationManager.getApplication().isInternal()) LOG.info("schedule " + task); final Application application = ApplicationManager.getApplication(); if (application.isUnitTestMode() || application.isHeadlessEnvironment() || !forceDumbMode && !myDumb && application.isReadAccessAllowed()) { final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator(); if (indicator != null) { indicator.pushState(); } try { HeavyProcessLatch.INSTANCE.processStarted(); task.performInDumbMode(indicator != null ? indicator : new EmptyProgressIndicator()); } finally { HeavyProcessLatch.INSTANCE.processFinished(); if (indicator != null) { indicator.popState(); } Disposer.dispose(task); } return; } UIUtil.invokeLaterIfNeeded( new DumbAwareRunnable() { @Override public void run() { if (myProject.isDisposed()) { return; } final ProgressIndicatorBase indicator = new ProgressIndicatorBase(); myProgresses.put(task, indicator); Disposer.register( task, new Disposable() { @Override public void dispose() { application.assertIsDispatchThread(); myProgresses.remove(task); } }); // ok to test and set the flag like this, because the change is always done from // dispatch thread if (!myDumb) { // always change dumb status inside write action. // This will ensure all active read actions are completed before the app goes dumb boolean startSuccess = application.runWriteAction( new Computable<Boolean>() { @Override public Boolean compute() { myDumb = true; try { myPublisher.enteredDumbMode(); } catch (Throwable e) { LOG.error(e); } try { startBackgroundProcess(task, indicator); } catch (Throwable e) { LOG.error("Failed to start background index update task", e); return false; } return true; } }); if (!startSuccess) { updateFinished(); } } else { myUpdatesQueue.addLast(task); } } }); }