use of com.intellij.concurrency.SensitiveProgressWrapper in project intellij-community by JetBrains.
the class ProgressIndicatorTest method testSOEUnderExtremelyNestedWrappedIndicator.
public void testSOEUnderExtremelyNestedWrappedIndicator() {
ProgressIndicator indicator = new DaemonProgressIndicator();
for (int i = 0; i < 10000; i++) {
indicator = new SensitiveProgressWrapper(indicator);
}
ProgressManager.getInstance().executeProcessUnderProgress(() -> {
ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
assertTrue(progressIndicator instanceof SensitiveProgressWrapper);
progressIndicator.checkCanceled();
progressIndicator.isCanceled();
}, indicator);
}
use of com.intellij.concurrency.SensitiveProgressWrapper in project intellij-community by JetBrains.
the class QuickDocUtil method runInReadActionWithWriteActionPriorityWithRetries.
/**
* Repeatedly tries to run given task in read action without blocking write actions (for this to work effectively the action should invoke
* {@link ProgressManager#checkCanceled()} or {@link ProgressIndicator#checkCanceled()} often enough).
*
* @param action task to run
* @param timeout timeout in milliseconds
* @param pauseBetweenRetries pause between retries in milliseconds
* @param progressIndicator optional progress indicator, which can be used to cancel the action externally
* @return {@code true} if the action succeeded to run without interruptions, {@code false} otherwise
*/
static boolean runInReadActionWithWriteActionPriorityWithRetries(@NotNull final Runnable action, long timeout, long pauseBetweenRetries, @Nullable ProgressIndicator progressIndicator) {
boolean result;
long deadline = System.currentTimeMillis() + timeout;
while (!(result = runInReadActionWithWriteActionPriority(action, progressIndicator == null ? null : new SensitiveProgressWrapper(progressIndicator))) && (progressIndicator == null || !progressIndicator.isCanceled()) && System.currentTimeMillis() < deadline) {
try {
TimeUnit.MILLISECONDS.sleep(pauseBetweenRetries);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
return result;
}
use of com.intellij.concurrency.SensitiveProgressWrapper in project intellij-community by JetBrains.
the class TextFieldWithAutoCompletionListProvider method fillCompletionVariants.
@Override
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull String prefix, @NotNull CompletionResultSet result) {
Collection<T> items = getItems(prefix, true, parameters);
addCompletionElements(result, this, items, -10000);
final ProgressManager progressManager = ProgressManager.getInstance();
ProgressIndicator mainIndicator = progressManager.getProgressIndicator();
final ProgressIndicator indicator = mainIndicator != null ? new SensitiveProgressWrapper(mainIndicator) : new EmptyProgressIndicator();
Future<Collection<T>> future = ApplicationManager.getApplication().executeOnPooledThread(() -> progressManager.runProcess(() -> getItems(prefix, false, parameters), indicator));
while (true) {
try {
Collection<T> tasks = future.get(100, TimeUnit.MILLISECONDS);
if (tasks != null) {
addCompletionElements(result, this, tasks, 0);
return;
}
} catch (ProcessCanceledException e) {
throw e;
} catch (Exception ignore) {
}
ProgressManager.checkCanceled();
}
}
use of com.intellij.concurrency.SensitiveProgressWrapper in project intellij-community by JetBrains.
the class GlobalInspectionContextImpl method runTools.
@Override
protected void runTools(@NotNull final AnalysisScope scope, boolean runGlobalToolsOnly, boolean isOfflineInspections) {
final ProgressIndicator progressIndicator = ProgressIndicatorProvider.getGlobalProgressIndicator();
if (progressIndicator == null) {
throw new IncorrectOperationException("Must be run under progress");
}
if (!isOfflineInspections && ApplicationManager.getApplication().isDispatchThread()) {
throw new IncorrectOperationException("Must not start inspections from within EDT");
}
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
throw new IncorrectOperationException("Must not start inspections from within write action");
}
// in offline inspection application we don't care about global read action
if (!isOfflineInspections && ApplicationManager.getApplication().isReadAccessAllowed()) {
throw new IncorrectOperationException("Must not start inspections from within global read action");
}
final InspectionManager inspectionManager = InspectionManager.getInstance(getProject());
((RefManagerImpl) getRefManager()).initializeAnnotators();
final List<Tools> globalTools = new ArrayList<>();
final List<Tools> localTools = new ArrayList<>();
final List<Tools> globalSimpleTools = new ArrayList<>();
initializeTools(globalTools, localTools, globalSimpleTools);
appendPairedInspectionsForUnfairTools(globalTools, globalSimpleTools, localTools);
runGlobalTools(scope, inspectionManager, globalTools, isOfflineInspections);
if (runGlobalToolsOnly || localTools.isEmpty() && globalSimpleTools.isEmpty())
return;
SearchScope searchScope = ReadAction.compute(scope::toSearchScope);
final Set<VirtualFile> localScopeFiles = searchScope instanceof LocalSearchScope ? new THashSet<>() : null;
for (Tools tools : globalSimpleTools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper) tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool) toolWrapper.getTool();
tool.inspectionStarted(inspectionManager, this, getPresentation(toolWrapper));
}
final boolean headlessEnvironment = ApplicationManager.getApplication().isHeadlessEnvironment();
final Map<String, InspectionToolWrapper> map = getInspectionWrappersMap(localTools);
final BlockingQueue<PsiFile> filesToInspect = new ArrayBlockingQueue<>(1000);
// use original progress indicator here since we don't want it to cancel on write action start
ProgressIndicator iteratingIndicator = new SensitiveProgressWrapper(progressIndicator);
Future<?> future = startIterateScopeInBackground(scope, localScopeFiles, headlessEnvironment, filesToInspect, iteratingIndicator);
Processor<PsiFile> processor = file -> {
ProgressManager.checkCanceled();
if (!ApplicationManagerEx.getApplicationEx().tryRunReadAction(() -> {
if (!file.isValid()) {
return;
}
LOG.assertTrue(scope.contains(file.getVirtualFile()), file.getName());
inspectFile(file, inspectionManager, localTools, globalSimpleTools, map);
})) {
throw new ProcessCanceledException();
}
boolean includeDoNotShow = includeDoNotShow(getCurrentProfile());
Stream.concat(getWrappersFromTools(localTools, file, includeDoNotShow).stream(), getWrappersFromTools(globalSimpleTools, file, includeDoNotShow).stream()).filter(wrapper -> wrapper.getTool() instanceof ExternalAnnotatorBatchInspection).forEach(wrapper -> {
ProblemDescriptor[] descriptors = ((ExternalAnnotatorBatchInspection) wrapper.getTool()).checkFile(file, this, inspectionManager);
InspectionToolPresentation toolPresentation = getPresentation(wrapper);
ReadAction.run(() -> LocalDescriptorsUtil.addProblemDescriptors(Arrays.asList(descriptors), false, this, null, CONVERT, toolPresentation));
});
return true;
};
try {
final Queue<PsiFile> filesFailedToInspect = new LinkedBlockingQueue<>();
while (true) {
Disposable disposable = Disposer.newDisposable();
ProgressIndicator wrapper = new SensitiveProgressWrapper(progressIndicator);
wrapper.start();
ProgressIndicatorUtils.forceWriteActionPriority(wrapper, disposable);
try {
// use wrapper here to cancel early when write action start but do not affect the original indicator
((JobLauncherImpl) JobLauncher.getInstance()).processQueue(filesToInspect, filesFailedToInspect, wrapper, TOMBSTONE, processor);
break;
} catch (ProcessCanceledException ignored) {
progressIndicator.checkCanceled();
// go on with the write and then resume processing the rest of the queue
assert !ApplicationManager.getApplication().isReadAccessAllowed();
assert !ApplicationManager.getApplication().isDispatchThread();
// wait for write action to complete
ApplicationManager.getApplication().runReadAction(EmptyRunnable.getInstance());
} finally {
Disposer.dispose(disposable);
}
}
} finally {
// tell file scanning thread to stop
iteratingIndicator.cancel();
// let file scanning thread a chance to put TOMBSTONE and complete
filesToInspect.clear();
try {
future.get(30, TimeUnit.SECONDS);
} catch (Exception e) {
LOG.error("Thread dump: \n" + ThreadDumper.dumpThreadsToString(), e);
}
}
progressIndicator.checkCanceled();
for (Tools tools : globalSimpleTools) {
GlobalInspectionToolWrapper toolWrapper = (GlobalInspectionToolWrapper) tools.getTool();
GlobalSimpleInspectionTool tool = (GlobalSimpleInspectionTool) toolWrapper.getTool();
ProblemDescriptionsProcessor problemDescriptionProcessor = getProblemDescriptionProcessor(toolWrapper, map);
tool.inspectionFinished(inspectionManager, this, problemDescriptionProcessor);
}
addProblemsToView(globalSimpleTools);
}
Aggregations