private static boolean sleepIfNeeded() {
   if (HeavyProcessLatch.INSTANCE.isInsideLowPriorityThread()) {
     TimeoutUtil.sleep(1);
     return true;
   }
   return false;
 }
Example #2
0
 @NotNull
 public static AccessToken workingTreeChangeStarted(@NotNull Project project) {
   ApplicationManager.getApplication()
       .getMessageBus()
       .syncPublisher(BatchFileChangeListener.TOPIC)
       .batchChangeStarted(project);
   return HeavyProcessLatch.INSTANCE.processStarted("Changing DVCS working tree");
 }
Example #3
0
  @Override
  public void reset() {
    // need this to ensure VFS operations will not block because of storage flushing
    // and other maintenance IO tasks run in background
    HeavyProcessLatch.INSTANCE.processStarted();

    try {
      myWasUiDisposed = false;

      myContext.reset();

      myProjectJdksModel.reset(myProject);

      Configurable toSelect = null;
      for (Configurable each : myName2Config) {
        if (myUiState.lastEditedConfigurable != null
            && myUiState.lastEditedConfigurable.equals(each.getDisplayName())) {
          toSelect = each;
        }
        if (each instanceof MasterDetailsComponent) {
          ((MasterDetailsComponent) each).setHistory(myHistory);
        }
        each.reset();
      }

      myHistory.clear();

      if (toSelect == null && myName2Config.size() > 0) {
        toSelect = myName2Config.iterator().next();
      }

      removeSelected();

      navigateTo(toSelect != null ? createPlaceFor(toSelect) : null, false);

      if (myUiState.proportion > 0) {
        mySplitter.setProportion(myUiState.proportion);
      }
    } finally {
      HeavyProcessLatch.INSTANCE.processFinished();
    }
  }
  @Override
  public void run() {
    while (!myDisposed) {
      boolean isEmpty;
      synchronized (filesToResolve) {
        isEmpty = filesToResolve.isEmpty();
      }
      if (enableVetoes.get() > 0
          || isEmpty
          || !resolveProcess.isDone()
          || HeavyProcessLatch.INSTANCE.isRunning()
          || PsiDocumentManager.getInstance(myProject).hasUncommitedDocuments()) {
        try {
          waitForQueue();
        } catch (InterruptedException e) {
          break;
        }
        continue;
      }
      final Set<VirtualFile> files = pollFilesToResolve();
      if (files.isEmpty()) continue;

      upToDate = false;

      myApplication.invokeLater(
          () -> {
            if (!resolveProcess.isDone()) return;
            log("Started to resolve " + files.size() + " files");

            Task.Backgroundable backgroundable =
                new Task.Backgroundable(myProject, "Resolving files...", false) {
                  @Override
                  public void run(@NotNull final ProgressIndicator indicator) {
                    if (!myApplication.isDisposed()) {
                      processBatch(indicator, files);
                    }
                  }
                };
            ProgressIndicator indicator;
            if (files.size() > 1) {
              // show progress
              indicator = new BackgroundableProcessIndicator(backgroundable);
            } else {
              indicator = new MyProgress();
            }
            resolveProcess =
                ((ProgressManagerImpl) ProgressManager.getInstance())
                    .runProcessWithProgressAsynchronously(backgroundable, indicator, null);
          },
          myProject.getDisposed());

      flushLog();
    }
  }
 @Nullable
 @Override
 protected CheckCanceledHook createCheckCanceledHook() {
   boolean shouldSleep =
       HeavyProcessLatch.INSTANCE.hasPrioritizedThread()
           && Registry.is("ide.prioritize.ui.thread", false);
   boolean hasEdtProgresses = myEdtProgresses.size() > 0;
   if (shouldSleep && hasEdtProgresses) return () -> pingProgresses() | sleepIfNeeded();
   if (shouldSleep) return ProgressManagerImpl::sleepIfNeeded;
   if (hasEdtProgresses) return this::pingProgresses;
   return null;
 }
  public void load(String path) throws IOException, InvalidDataException {
    getStateStore().setOptionsPath(path);
    getStateStore().setConfigPath(PathManager.getConfigPath());
    myIsFiringLoadingEvent = true;
    try {
      fireBeforeApplicationLoaded();
    } finally {
      myIsFiringLoadingEvent = false;
    }

    loadComponentRoamingTypes();

    HeavyProcessLatch.INSTANCE.processStarted();
    try {
      getStateStore().load();
    } catch (StateStorageException e) {
      throw new IOException(e.getMessage());
    } finally {
      HeavyProcessLatch.INSTANCE.processFinished();
    }
  }
    public static void flushSome() {
      if (!isDirty() || HeavyProcessLatch.INSTANCE.isRunning()) return;

      try {
        w.lock();
        if (myFlushingFuture == null) {
          return; // avoid NPE when close has already taken place
        }
        myNames.force();

        final boolean attribsFlushed = myAttributes.flushSome();
        final boolean contentsFlushed = myContents.flushSome();
        if (attribsFlushed && contentsFlushed) {
          markClean();
          myRecords.force();
        }
      } finally {
        w.unlock();
      }
    }
  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);
            }
          }
        });
  }
  @NotNull
  protected DaemonCodeAnalyzerStatus getDaemonCodeAnalyzerStatus(
      @NotNull SeverityRegistrar severityRegistrar) {
    DaemonCodeAnalyzerStatus status = new DaemonCodeAnalyzerStatus();
    if (myFile == null) {
      status.reasonWhyDisabled = "No file";
      status.errorAnalyzingFinished = true;
      return status;
    }
    if (myProject != null && myProject.isDisposed()) {
      status.reasonWhyDisabled = "Project is disposed";
      status.errorAnalyzingFinished = true;
      return status;
    }
    if (!myDaemonCodeAnalyzer.isHighlightingAvailable(myFile)) {
      if (!myFile.isPhysical()) {
        status.reasonWhyDisabled = "File is generated";
        status.errorAnalyzingFinished = true;
        return status;
      } else if (myFile instanceof PsiCompiledElement) {
        status.reasonWhyDisabled = "File is decompiled";
        status.errorAnalyzingFinished = true;
        return status;
      }
      final FileType fileType = myFile.getFileType();
      if (fileType.isBinary()) {
        status.reasonWhyDisabled = "File is binary";
        status.errorAnalyzingFinished = true;
        return status;
      }
      status.reasonWhyDisabled = "Highlighting is disabled for this file";
      status.errorAnalyzingFinished = true;
      return status;
    }

    FileViewProvider provider = myFile.getViewProvider();
    Set<Language> languages = provider.getLanguages();
    HighlightingSettingsPerFile levelSettings = HighlightingSettingsPerFile.getInstance(myProject);
    boolean shouldHighlight = languages.isEmpty();
    for (Language language : languages) {
      PsiFile root = provider.getPsi(language);
      FileHighlightingSetting level = levelSettings.getHighlightingSettingForRoot(root);
      shouldHighlight |= level != FileHighlightingSetting.SKIP_HIGHLIGHTING;
    }
    if (!shouldHighlight) {
      status.reasonWhyDisabled = "Highlighting level is None";
      status.errorAnalyzingFinished = true;
      return status;
    }

    if (HeavyProcessLatch.INSTANCE.isRunning()) {
      status.reasonWhySuspended =
          StringUtil.defaultIfEmpty(
              HeavyProcessLatch.INSTANCE.getRunningOperationName(), "Heavy operation is running");
      status.errorAnalyzingFinished = true;
      return status;
    }

    status.errorCount = errorCount.clone();
    fillDaemonCodeAnalyzerErrorsStatus(status, severityRegistrar);
    List<TextEditorHighlightingPass> passes =
        myDaemonCodeAnalyzer.getPassesToShowProgressFor(myDocument);
    status.passStati =
        passes.isEmpty()
            ? Collections.<ProgressableTextEditorHighlightingPass>emptyList()
            : new ArrayList<>(passes.size());
    //noinspection ForLoopReplaceableByForEach
    for (int i = 0; i < passes.size(); i++) {
      TextEditorHighlightingPass tepass = passes.get(i);
      if (!(tepass instanceof ProgressableTextEditorHighlightingPass)) continue;
      ProgressableTextEditorHighlightingPass pass = (ProgressableTextEditorHighlightingPass) tepass;

      if (pass.getProgress() < 0) continue;
      status.passStati.add(pass);
    }
    status.errorAnalyzingFinished = myDaemonCodeAnalyzer.isAllAnalysisFinished(myFile);
    status.reasonWhySuspended =
        myDaemonCodeAnalyzer.isUpdateByTimerEnabled() ? null : "Highlighting is paused temporarily";

    return status;
  }
  private void initListeners(@NotNull MessageBus messageBus, @NotNull PsiManager psiManager) {
    messageBus
        .connect()
        .subscribe(
            VirtualFileManager.VFS_CHANGES,
            new BulkFileListener.Adapter() {
              @Override
              public void after(@NotNull List<? extends VFileEvent> events) {
                fileCount.set(0);
                List<VirtualFile> files =
                    ContainerUtil.mapNotNull(
                        events,
                        new Function<VFileEvent, VirtualFile>() {
                          @Override
                          public VirtualFile fun(VFileEvent event) {
                            return event.getFile();
                          }
                        });
                queue(files, "VFS events " + events.size());
              }
            });
    psiManager.addPsiTreeChangeListener(
        new PsiTreeChangeAdapter() {
          @Override
          public void childrenChanged(@NotNull PsiTreeChangeEvent event) {
            PsiFile file = event.getFile();
            VirtualFile virtualFile = PsiUtilCore.getVirtualFile(file);
            if (virtualFile != null) {
              queue(Collections.singletonList(virtualFile), event);
            }
          }

          @Override
          public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
            childrenChanged(event);
          }
        });

    messageBus
        .connect()
        .subscribe(
            DumbService.DUMB_MODE,
            new DumbService.DumbModeListener() {
              @Override
              public void enteredDumbMode() {
                disable();
              }

              @Override
              public void exitDumbMode() {
                enable();
              }
            });
    messageBus
        .connect()
        .subscribe(
            PowerSaveMode.TOPIC,
            new PowerSaveMode.Listener() {
              @Override
              public void powerSaveStateChanged() {
                if (PowerSaveMode.isEnabled()) {
                  enable();
                } else {
                  disable();
                }
              }
            });
    myApplication.addApplicationListener(
        new ApplicationAdapter() {
          @Override
          public void beforeWriteActionStart(@NotNull Object action) {
            disable();
          }

          @Override
          public void writeActionFinished(@NotNull Object action) {
            enable();
          }

          @Override
          public void applicationExiting() {
            disable();
          }
        },
        this);
    VirtualFileManager.getInstance()
        .addVirtualFileManagerListener(
            new VirtualFileManagerListener() {
              @Override
              public void beforeRefreshStart(boolean asynchronous) {
                disable();
              }

              @Override
              public void afterRefreshFinish(boolean asynchronous) {
                enable();
              }
            },
            this);
    HeavyProcessLatch.INSTANCE.addListener(
        new HeavyProcessLatch.HeavyProcessListener() {
          @Override
          public void processStarted() {}

          @Override
          public void processFinished() {
            wakeUp();
          }
        },
        this);
  }