fix "Calling invokeAndWait from read-action leads to possible deadlock."

This commit is contained in:
Vladimir Krivosheev
2014-11-10 19:28:23 +01:00
parent 56cfa904e8
commit 97fd2fa3db
2 changed files with 23 additions and 19 deletions
@@ -16,12 +16,13 @@
package com.intellij.openapi.roots.impl.storage;
import com.intellij.application.options.PathMacrosCollector;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.*;
import com.intellij.openapi.components.impl.stores.IModuleStore;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.ProjectBundle;
import com.intellij.openapi.project.impl.ProjectMacrosUtil;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ModuleRootModel;
@@ -65,9 +66,12 @@ public class ClasspathStorage implements StateStorage {
@NonNls private static final String COMPONENT_TAG = "component";
private final ClasspathStorageProvider.ClasspathConverter myConverter;
private final TrackingPathMacroSubstitutor myTrackingPathMacroSubstitutor;
public ClasspathStorage(Module module) {
public ClasspathStorage(@NotNull Module module, @NotNull IModuleStore moduleStore) {
myConverter = getProvider(ClassPathStorageUtil.getStorageType(module)).createConverter(module);
myTrackingPathMacroSubstitutor = moduleStore.getStateStorageManager().getMacroSubstitutor();
final VirtualFileTracker virtualFileTracker = ServiceManager.getService(VirtualFileTracker.class);
if (virtualFileTracker != null) {
List<VirtualFile> files = new SmartList<VirtualFile>();
@@ -102,13 +106,11 @@ public class ClasspathStorage implements StateStorage {
assert stateClass == ModuleRootManagerImpl.ModuleRootManagerState.class;
try {
final Module module = ((ModuleRootManagerImpl)component).getModule();
final Element element = new Element(COMPONENT_TAG);
final Set<String> macros;
Element element = new Element(COMPONENT_TAG);
ModifiableRootModel model = null;
try {
model = ((ModuleRootManagerImpl)component).getModifiableModel();
macros = myConverter.getClasspath(model, element);
myConverter.getClasspath(model, element);
}
finally {
if (model != null) {
@@ -116,13 +118,11 @@ public class ClasspathStorage implements StateStorage {
}
}
final boolean macrosOk = ProjectMacrosUtil.checkNonIgnoredMacros(module.getProject(), macros);
PathMacroManager.getInstance(module).expandPaths(element);
myTrackingPathMacroSubstitutor.expandPaths(element);
myTrackingPathMacroSubstitutor.addUnknownMacros(componentName, PathMacrosCollector.getMacroNames(element));
ModuleRootManagerImpl.ModuleRootManagerState moduleRootManagerState = new ModuleRootManagerImpl.ModuleRootManagerState();
moduleRootManagerState.readExternal(element);
if (!macrosOk) {
throw new StateStorageException(ProjectBundle.message("project.load.undefined.path.variables.error"));
}
//noinspection unchecked
return (T)moduleRootManagerState;
}
@@ -31,6 +31,8 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.SmartList;
import gnu.trove.THashSet;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
@@ -46,8 +48,7 @@ import org.jetbrains.jps.eclipse.model.JpsEclipseClasspathSerializer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Collections;
import java.util.Set;
/**
@@ -191,26 +192,29 @@ public class EclipseClasspathStorageProvider implements ClasspathStorageProvider
}
@Override
public Set<String> getClasspath(ModifiableRootModel model, final Element element) throws IOException, InvalidDataException {
public Set<String> getClasspath(@NotNull ModifiableRootModel model, @NotNull Element element) throws IOException, InvalidDataException {
try {
final HashSet<String> usedVariables = new HashSet<String>();
final CachedXmlDocumentSet documentSet = getFileSet();
CachedXmlDocumentSet documentSet = getFileSet();
String path = documentSet.getParent(EclipseXml.PROJECT_FILE);
if (!documentSet.exists(EclipseXml.PROJECT_FILE)) {
if (!documentSet.exists(EclipseXml.CLASSPATH_FILE)) {
return usedVariables;
return Collections.emptySet();
}
path = documentSet.getParent(EclipseXml.CLASSPATH_FILE);
}
final EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, module.getProject(), null);
Set<String> usedVariables;
EclipseClasspathReader classpathReader = new EclipseClasspathReader(path, module.getProject(), null);
classpathReader.init(model);
if (documentSet.exists(EclipseXml.CLASSPATH_FILE)) {
classpathReader.readClasspath(model, new ArrayList<String>(), new ArrayList<String>(), usedVariables, new HashSet<String>(), null,
usedVariables = new THashSet<String>();
classpathReader.readClasspath(model, new SmartList<String>(), new SmartList<String>(), usedVariables, new THashSet<String>(), null,
documentSet.read(EclipseXml.CLASSPATH_FILE, false).getRootElement());
}
else {
EclipseClasspathReader.setOutputUrl(model, path + "/bin");
usedVariables = Collections.emptySet();
}
final String eml = model.getModule().getName() + EclipseXml.IDEA_SETTINGS_POSTFIX;
if (documentSet.exists(eml)) {