1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-20 15:35:24 +02:00

Bug 228236 - ConcurrentModificationException when opening source file

This commit is contained in:
Anton Leherbauer 2008-11-20 16:10:22 +00:00
parent cd8a4b82b0
commit 793eff3eb2
2 changed files with 381 additions and 320 deletions

View file

@ -60,84 +60,88 @@ import org.w3c.dom.NodeList;
* *
* @author vhirsl * @author vhirsl
*/ */
public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoCollectorCleaner { public final class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoCollectorCleaner {
private static final int INCLUDE_PATH = 1; private static final int INCLUDE_PATH = 1;
private static final int QUOTE_INCLUDE_PATH = 2; private static final int QUOTE_INCLUDE_PATH = 2;
private static final int INCLUDE_FILE = 3; private static final int INCLUDE_FILE = 3;
private static final int MACROS_FILE = 4; private static final int MACROS_FILE = 4;
public class ScannerInfoData implements IDiscoveredScannerInfoSerializable { private class ScannerInfoData implements IDiscoveredScannerInfoSerializable {
private Map commandIdToFilesMap; // command id and set of files it applies to private final Map<Integer, Set<IFile>> commandIdToFilesMap; // command id and set of files it applies to
private Map fileToCommandIdMap; // maps each file to the corresponding command id private final Map<IFile, Integer> fileToCommandIdMap; // maps each file to the corresponding command id
private Map commandIdCommandMap; // map of all commands private final Map<Integer, CCommandDSC> commandIdCommandMap; // map of all commands
public ScannerInfoData() { public ScannerInfoData() {
commandIdCommandMap = new LinkedHashMap(); // [commandId, command] commandIdCommandMap = new LinkedHashMap<Integer, CCommandDSC>(); // [commandId, command]
fileToCommandIdMap = new HashMap(); // [file, commandId] fileToCommandIdMap = new HashMap<IFile, Integer>(); // [file, commandId]
commandIdToFilesMap = new HashMap(); // [commandId, set of files] commandIdToFilesMap = new HashMap<Integer, Set<IFile>>(); // [commandId, set of files]
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#serialize(org.w3c.dom.Element) * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#serialize(org.w3c.dom.Element)
*/ */
public void serialize(Element collectorElem) { public void serialize(Element collectorElem) {
Document doc = collectorElem.getOwnerDocument(); synchronized (PerFileSICollector.this.fLock) {
Document doc = collectorElem.getOwnerDocument();
List commandIds = new ArrayList(commandIdCommandMap.keySet()); List<Integer> commandIds = new ArrayList<Integer>(commandIdCommandMap.keySet());
Collections.sort(commandIds); Collections.sort(commandIds);
for (Iterator i = commandIds.iterator(); i.hasNext(); ) { for (Iterator<Integer> i = commandIds.iterator(); i.hasNext(); ) {
Integer commandId = (Integer) i.next(); Integer commandId = i.next();
CCommandDSC command = (CCommandDSC) commandIdCommandMap.get(commandId); CCommandDSC command = commandIdCommandMap.get(commandId);
Element cmdElem = doc.createElement(CC_ELEM); Element cmdElem = doc.createElement(CC_ELEM);
collectorElem.appendChild(cmdElem); collectorElem.appendChild(cmdElem);
cmdElem.setAttribute(ID_ATTR, commandId.toString()); cmdElem.setAttribute(ID_ATTR, commandId.toString());
cmdElem.setAttribute(FILE_TYPE_ATTR, command.appliesToCPPFileType() ? "c++" : "c"); //$NON-NLS-1$ //$NON-NLS-2$ cmdElem.setAttribute(FILE_TYPE_ATTR, command.appliesToCPPFileType() ? "c++" : "c"); //$NON-NLS-1$ //$NON-NLS-2$
// write command and scanner info // write command and scanner info
command.serialize(cmdElem); command.serialize(cmdElem);
// write files command applies to // write files command applies to
Element filesElem = doc.createElement(APPLIES_TO_ATTR); Element filesElem = doc.createElement(APPLIES_TO_ATTR);
cmdElem.appendChild(filesElem); cmdElem.appendChild(filesElem);
Set files = (Set) commandIdToFilesMap.get(commandId); Set<IFile> files = commandIdToFilesMap.get(commandId);
if (files != null) { if (files != null) {
for (Iterator j = files.iterator(); j.hasNext(); ) { for (Iterator<IFile> j = files.iterator(); j.hasNext(); ) {
Element fileElem = doc.createElement(FILE_ELEM); Element fileElem = doc.createElement(FILE_ELEM);
IFile file = (IFile) j.next(); IFile file = j.next();
IPath path = file.getProjectRelativePath(); IPath path = file.getProjectRelativePath();
fileElem.setAttribute(PATH_ATTR, path.toString()); fileElem.setAttribute(PATH_ATTR, path.toString());
filesElem.appendChild(fileElem); filesElem.appendChild(fileElem);
} }
} }
} }
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#deserialize(org.w3c.dom.Element) * @see org.eclipse.cdt.make.internal.core.scannerconfig.DiscoveredScannerInfoStore.IDiscoveredScannerInfoSerializable#deserialize(org.w3c.dom.Element)
*/ */
public void deserialize(Element collectorElem) { public void deserialize(Element collectorElem) {
for (Node child = collectorElem.getFirstChild(); child != null; child = child.getNextSibling()) { synchronized (PerFileSICollector.this.fLock) {
if (child.getNodeName().equals(CC_ELEM)) { for (Node child = collectorElem.getFirstChild(); child != null; child = child.getNextSibling()) {
Element cmdElem = (Element) child; if (child.getNodeName().equals(CC_ELEM)) {
boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); //$NON-NLS-1$ Element cmdElem = (Element) child;
CCommandDSC command = new CCommandDSC(cppFileType, project); boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); //$NON-NLS-1$
command.setCommandId(Integer.parseInt(cmdElem.getAttribute(ID_ATTR))); CCommandDSC command = new CCommandDSC(cppFileType, project);
// deserialize command command.setCommandId(Integer.parseInt(cmdElem.getAttribute(ID_ATTR)));
command.deserialize(cmdElem); // deserialize command
// get set of files the command applies to command.deserialize(cmdElem);
NodeList appliesList = cmdElem.getElementsByTagName(APPLIES_TO_ATTR); // get set of files the command applies to
if (appliesList.getLength() > 0) { NodeList appliesList = cmdElem.getElementsByTagName(APPLIES_TO_ATTR);
Element appliesElem = (Element) appliesList.item(0); if (appliesList.getLength() > 0) {
NodeList fileList = appliesElem.getElementsByTagName(FILE_ELEM); Element appliesElem = (Element) appliesList.item(0);
for (int i = 0; i < fileList.getLength(); ++i) { NodeList fileList = appliesElem.getElementsByTagName(FILE_ELEM);
Element fileElem = (Element) fileList.item(i); for (int i = 0; i < fileList.getLength(); ++i) {
String fileName = fileElem.getAttribute(PATH_ATTR); Element fileElem = (Element) fileList.item(i);
IFile file = project.getFile(fileName); String fileName = fileElem.getAttribute(PATH_ATTR);
addCompilerCommand(file, command); IFile file = project.getFile(fileName);
} addCompilerCommand(file, command);
applyFileDeltas(); }
} applyFileDeltas();
} }
} }
}
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -154,7 +158,7 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
IPath[] quoteIncludePaths; IPath[] quoteIncludePaths;
IPath[] includeFiles; IPath[] includeFiles;
IPath[] macrosFiles; IPath[] macrosFiles;
Map definedSymbols; Map<String, String> definedSymbols;
public boolean isEmpty() { public boolean isEmpty() {
return (includePaths.length == 0 && return (includePaths.length == 0 &&
quoteIncludePaths.length == 0 && quoteIncludePaths.length == 0 &&
@ -172,19 +176,22 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
private static final String FILE_ELEM = "file"; //$NON-NLS-1$ private static final String FILE_ELEM = "file"; //$NON-NLS-1$
private static final String PATH_ATTR = "path"; //$NON-NLS-1$ private static final String PATH_ATTR = "path"; //$NON-NLS-1$
IProject project; private IProject project;
InfoContext context; private InfoContext context;
private ScannerInfoData sid; // scanner info data private ScannerInfoData sid; // scanner info data
private ProjectScannerInfo psi = null; // sum of all scanner info private ProjectScannerInfo psi = null; // sum of all scanner info
// private List siChangedForFileList; // list of files for which scanner info has changed // private List siChangedForFileList; // list of files for which scanner info has changed
private Map siChangedForFileMap; // (file, comandId) map for deltas private final Map<IResource, Integer> siChangedForFileMap; // (file, comandId) map for deltas
private List siChangedForCommandIdList; // list of command ids for which scanner info has changed private final List<Integer> siChangedForCommandIdList; // list of command ids for which scanner info has changed
private SortedSet freeCommandIdPool; // sorted set of free command ids private final SortedSet<Integer> freeCommandIdPool; // sorted set of free command ids
private int commandIdCounter = 0; private int commandIdCounter = 0;
/** monitor for data access */
private final Object fLock = new Object();
/** /**
* *
*/ */
@ -192,10 +199,10 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
sid = new ScannerInfoData(); sid = new ScannerInfoData();
// siChangedForFileList = new ArrayList(); // siChangedForFileList = new ArrayList();
siChangedForFileMap = new HashMap(); siChangedForFileMap = new HashMap<IResource, Integer>();
siChangedForCommandIdList = new ArrayList(); siChangedForCommandIdList = new ArrayList<Integer>();
freeCommandIdPool = new TreeSet(); freeCommandIdPool = new TreeSet<Integer>();
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -221,14 +228,16 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map) * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map)
*/ */
public synchronized void contributeToScannerConfig(Object resource, Map scannerInfo) { public void contributeToScannerConfig(Object resource, Map scannerInfo) {
// check the resource // check the resource
String errorMessage = null; String errorMessage = null;
if (resource == null) { if (resource == null) {
errorMessage = "resource is null";//$NON-NLS-1$ errorMessage = "resource is null";//$NON-NLS-1$
} }
else if (resource instanceof Integer) { else if (resource instanceof Integer) {
addScannerInfo(((Integer)resource), scannerInfo); synchronized (fLock) {
addScannerInfo(((Integer)resource), scannerInfo);
}
return; return;
} }
else if (!(resource instanceof IFile)) { else if (!(resource instanceof IFile)) {
@ -247,17 +256,19 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
IFile file = (IFile) resource; IFile file = (IFile) resource;
for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) { synchronized (fLock) {
ScannerInfoTypes type = (ScannerInfoTypes) i.next(); for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) {
if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { ScannerInfoTypes type = (ScannerInfoTypes) i.next();
List commands = (List) scannerInfo.get(type); if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) {
for (Iterator j = commands.iterator(); j.hasNext(); ) { List commands = (List) scannerInfo.get(type);
addCompilerCommand(file, (CCommandDSC) j.next()); for (Iterator j = commands.iterator(); j.hasNext(); ) {
} addCompilerCommand(file, (CCommandDSC) j.next());
} }
else { }
addScannerInfo(type, (List) scannerInfo.get(type)); else {
} addScannerInfo(type, (List) scannerInfo.get(type));
}
}
} }
} }
@ -266,15 +277,16 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @param scannerInfo * @param scannerInfo
*/ */
private void addScannerInfo(Integer commandId, Map scannerInfo) { private void addScannerInfo(Integer commandId, Map scannerInfo) {
CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(commandId); assert Thread.holdsLock(fLock);
CCommandDSC cmd = sid.commandIdCommandMap.get(commandId);
if (cmd != null) { if (cmd != null) {
List siItem = (List) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS); List<String> siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS);
cmd.setSymbols(siItem); cmd.setSymbols(siItem);
siItem = (List) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS); siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS);
siItem = CygpathTranslator.translateIncludePaths(project, siItem); siItem = CygpathTranslator.translateIncludePaths(project, siItem);
siItem = CCommandDSC.makeRelative(project, siItem); siItem = CCommandDSC.makeRelative(project, siItem);
cmd.setIncludes(siItem); cmd.setIncludes(siItem);
siItem = (List) scannerInfo.get(ScannerInfoTypes.QUOTE_INCLUDE_PATHS); siItem = (List<String>) scannerInfo.get(ScannerInfoTypes.QUOTE_INCLUDE_PATHS);
siItem = CygpathTranslator.translateIncludePaths(project, siItem); siItem = CygpathTranslator.translateIncludePaths(project, siItem);
siItem = CCommandDSC.makeRelative(project, siItem); siItem = CCommandDSC.makeRelative(project, siItem);
cmd.setQuoteIncludes(siItem); cmd.setQuoteIncludes(siItem);
@ -287,16 +299,17 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @param file * @param file
* @param object * @param object
*/ */
void addCompilerCommand(IFile file, CCommandDSC cmd) { private void addCompilerCommand(IFile file, CCommandDSC cmd) {
List existingCommands = new ArrayList(sid.commandIdCommandMap.values()); assert Thread.holdsLock(fLock);
List<CCommandDSC> existingCommands = new ArrayList<CCommandDSC>(sid.commandIdCommandMap.values());
int index = existingCommands.indexOf(cmd); int index = existingCommands.indexOf(cmd);
if (index != -1) { if (index != -1) {
cmd = (CCommandDSC) existingCommands.get(index); cmd = existingCommands.get(index);
} }
else { else {
int commandId = -1; int commandId = -1;
if (!freeCommandIdPool.isEmpty()) { if (!freeCommandIdPool.isEmpty()) {
Integer freeCommandId = (Integer) freeCommandIdPool.first(); Integer freeCommandId = freeCommandIdPool.first();
freeCommandIdPool.remove(freeCommandId); freeCommandIdPool.remove(freeCommandId);
commandId = freeCommandId.intValue(); commandId = freeCommandId.intValue();
} }
@ -315,8 +328,9 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @param cmd * @param cmd
*/ */
private void generateFileDelta(IFile file, CCommandDSC cmd) { private void generateFileDelta(IFile file, CCommandDSC cmd) {
assert Thread.holdsLock(fLock);
Integer commandId = cmd.getCommandIdAsInteger(); Integer commandId = cmd.getCommandIdAsInteger();
Integer oldCommandId = (Integer) sid.fileToCommandIdMap.get(file); Integer oldCommandId = sid.fileToCommandIdMap.get(file);
if (oldCommandId != null && oldCommandId.equals(commandId)) { if (oldCommandId != null && oldCommandId.equals(commandId)) {
// already exists; remove form delta // already exists; remove form delta
@ -332,18 +346,19 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @param file * @param file
* @param cmd * @param cmd
*/ */
void applyFileDeltas() { private void applyFileDeltas() {
for (Iterator i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) { assert Thread.holdsLock(fLock);
for (Iterator<IResource> i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) {
IFile file = (IFile) i.next(); IFile file = (IFile) i.next();
Integer commandId = (Integer) siChangedForFileMap.get(file); Integer commandId = siChangedForFileMap.get(file);
if (commandId != null) { if (commandId != null) {
// update sid.commandIdToFilesMap // update sid.commandIdToFilesMap
Set fileSet = (Set) sid.commandIdToFilesMap.get(commandId); Set<IFile> fileSet = sid.commandIdToFilesMap.get(commandId);
if (fileSet == null) { if (fileSet == null) {
fileSet = new HashSet(); fileSet = new HashSet<IFile>();
sid.commandIdToFilesMap.put(commandId, fileSet); sid.commandIdToFilesMap.put(commandId, fileSet);
CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(commandId); CCommandDSC cmd = sid.commandIdCommandMap.get(commandId);
if (cmd != null) { if (cmd != null) {
cmd.resolveOptions(project); cmd.resolveOptions(project);
} }
@ -351,13 +366,13 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
if (fileSet.add(file)) { if (fileSet.add(file)) {
// update fileToCommandIdsMap // update fileToCommandIdsMap
boolean change = true; boolean change = true;
Integer oldCommandId = (Integer) sid.fileToCommandIdMap.get(file); Integer oldCommandId = sid.fileToCommandIdMap.get(file);
if (oldCommandId != null) { if (oldCommandId != null) {
if (oldCommandId.equals(commandId)) { if (oldCommandId.equals(commandId)) {
change = false; change = false;
} }
else { else {
Set oldFileSet = (Set) sid.commandIdToFilesMap.get(oldCommandId); Set oldFileSet = sid.commandIdToFilesMap.get(oldCommandId);
if (oldFileSet != null) { if (oldFileSet != null) {
oldFileSet.remove(file); oldFileSet.remove(file);
} }
@ -378,7 +393,8 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
} }
private void generateProjectScannerInfo() { private void generateProjectScannerInfo() {
psi = new ProjectScannerInfo(); assert Thread.holdsLock(fLock);
psi = new ProjectScannerInfo();
psi.includePaths = getAllIncludePaths(INCLUDE_PATH); psi.includePaths = getAllIncludePaths(INCLUDE_PATH);
psi.quoteIncludePaths = getAllIncludePaths(QUOTE_INCLUDE_PATH); psi.quoteIncludePaths = getAllIncludePaths(QUOTE_INCLUDE_PATH);
psi.includeFiles = getAllIncludePaths(INCLUDE_FILE); psi.includeFiles = getAllIncludePaths(INCLUDE_FILE);
@ -387,6 +403,7 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
} }
private void removeUnusedCommands() { private void removeUnusedCommands() {
assert Thread.holdsLock(fLock);
for (Iterator i = sid.commandIdToFilesMap.entrySet().iterator(); i.hasNext(); ) { for (Iterator i = sid.commandIdToFilesMap.entrySet().iterator(); i.hasNext(); ) {
Entry entry = (Entry) i.next(); Entry entry = (Entry) i.next();
Integer cmdId = (Integer) entry.getKey(); Integer cmdId = (Integer) entry.getKey();
@ -396,14 +413,14 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
freeCommandIdPool.add(cmdId); freeCommandIdPool.add(cmdId);
} }
} }
for (Iterator i = freeCommandIdPool.iterator(); i.hasNext(); ) { for (Iterator<Integer> i = freeCommandIdPool.iterator(); i.hasNext(); ) {
Integer cmdId = (Integer) i.next(); Integer cmdId = i.next();
// the command does not have any files associated; remove // the command does not have any files associated; remove
sid.commandIdCommandMap.remove(cmdId); sid.commandIdCommandMap.remove(cmdId);
sid.commandIdToFilesMap.remove(cmdId); sid.commandIdToFilesMap.remove(cmdId);
} }
while (!freeCommandIdPool.isEmpty()) { while (!freeCommandIdPool.isEmpty()) {
Integer last = (Integer) freeCommandIdPool.last(); Integer last = freeCommandIdPool.last();
if (last.intValue() == commandIdCounter) { if (last.intValue() == commandIdCounter) {
freeCommandIdPool.remove(last); freeCommandIdPool.remove(last);
--commandIdCounter; --commandIdCounter;
@ -431,30 +448,31 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$ monitor.beginTask(MakeMessages.getString("ScannerInfoCollector.Processing"), 100); //$NON-NLS-1$
// removeUnusedCommands(); // removeUnusedCommands();
monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$ monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Processing")); //$NON-NLS-1$
if (scannerInfoChanged()) { synchronized (fLock) {
applyFileDeltas(); if (scannerInfoChanged()) {
removeUnusedCommands(); applyFileDeltas();
monitor.worked(50); removeUnusedCommands();
monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$ monitor.worked(50);
try { monitor.subTask(MakeMessages.getString("ScannerInfoCollector.Updating") + project.getName()); //$NON-NLS-1$
// update scanner configuration try {
// MakeCorePlugin.getDefault().getDiscoveryManager(). // update scanner configuration
// updateDiscoveredInfo(createPathInfoObject(), siChangedForFileList); // MakeCorePlugin.getDefault().getDiscoveryManager().
IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project, context); // updateDiscoveredInfo(createPathInfoObject(), siChangedForFileList);
if (!(pathInfo instanceof IPerFileDiscoveredPathInfo)) { IDiscoveredPathInfo pathInfo = MakeCorePlugin.getDefault().getDiscoveryManager().getDiscoveredInfo(project, context);
pathInfo = createPathInfoObject(); if (!(pathInfo instanceof IPerFileDiscoveredPathInfo)) {
} pathInfo = createPathInfoObject();
MakeCorePlugin.getDefault().getDiscoveryManager(). }
updateDiscoveredInfo(context, pathInfo, context.isDefaultContext(), new ArrayList(siChangedForFileMap.keySet())); MakeCorePlugin.getDefault().getDiscoveryManager().
monitor.worked(50); updateDiscoveredInfo(context, pathInfo, context.isDefaultContext(), new ArrayList<IResource>(siChangedForFileMap.keySet()));
} catch (CoreException e) { monitor.worked(50);
MakeCorePlugin.log(e); } catch (CoreException e) {
} MakeCorePlugin.log(e);
}
}
// siChangedForFileList.clear();
siChangedForFileMap.clear();
siChangedForCommandIdList.clear();
} }
// siChangedForFileList.clear();
siChangedForFileMap.clear();
siChangedForCommandIdList.clear();
monitor.done(); monitor.done();
} }
@ -466,6 +484,7 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
} }
private boolean scannerInfoChanged() { private boolean scannerInfoChanged() {
assert Thread.holdsLock(fLock);
// return !siChangedForFileList.isEmpty(); // return !siChangedForFileList.isEmpty();
return !siChangedForFileMap.isEmpty(); return !siChangedForFileMap.isEmpty();
} }
@ -473,8 +492,8 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes) * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes)
*/ */
public List getCollectedScannerInfo(Object resource, ScannerInfoTypes type) { public List<CCommandDSC> getCollectedScannerInfo(Object resource, ScannerInfoTypes type) {
List rv = new ArrayList(); List<CCommandDSC> rv = new ArrayList<CCommandDSC>();
// check the resource // check the resource
String errorMessage = null; String errorMessage = null;
if (resource == null) { if (resource == null) {
@ -492,42 +511,47 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
if (errorMessage != null) { if (errorMessage != null) {
TraceUtil.outputError("PerProjectSICollector.getCollectedScannerInfo : ", errorMessage); //$NON-NLS-1$ TraceUtil.outputError("PerProjectSICollector.getCollectedScannerInfo : ", errorMessage); //$NON-NLS-1$
return rv;
} }
else if (project.equals(((IResource)resource).getProject())) { if (project.equals(((IResource)resource).getProject())) {
if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) {
for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { synchronized (fLock) {
Integer cmdId = (Integer) i.next(); for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) {
Set fileSet = (Set) sid.commandIdToFilesMap.get(cmdId); Integer cmdId = i.next();
if (fileSet != null && !fileSet.isEmpty()) { Set<IFile> fileSet = sid.commandIdToFilesMap.get(cmdId);
rv.add(sid.commandIdCommandMap.get(cmdId)); if (fileSet != null && !fileSet.isEmpty()) {
} rv.add(sid.commandIdCommandMap.get(cmdId));
} }
}
}
}
else if (type.equals(ScannerInfoTypes.UNDISCOVERED_COMPILER_COMMAND)) {
// if (!siChangedForFileList.isEmpty()) {
synchronized (fLock) {
if (scannerInfoChanged()) {
if (siChangedForCommandIdList.isEmpty()) {
// for (Iterator i = siChangedForFileList.iterator(); i.hasNext(); ) {
for (Iterator<IResource> i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) {
// IPath path = (IPath) i.next();
IFile file = (IFile) i.next();
Integer cmdId = siChangedForFileMap.get(file);
if (cmdId != null) {
if (!siChangedForCommandIdList.contains(cmdId)) {
siChangedForCommandIdList.add(cmdId);
}
}
}
}
Collections.sort(siChangedForCommandIdList);
for (Iterator<Integer> i = siChangedForCommandIdList.iterator(); i.hasNext(); ) {
Integer cmdId = i.next();
CCommandDSC command = sid.commandIdCommandMap.get(cmdId);
rv.add(command);
}
}
}
} }
else if (type.equals(ScannerInfoTypes.UNDISCOVERED_COMPILER_COMMAND)) { }
// if (!siChangedForFileList.isEmpty()) {
if (scannerInfoChanged()) {
if (siChangedForCommandIdList.isEmpty()) {
// for (Iterator i = siChangedForFileList.iterator(); i.hasNext(); ) {
for (Iterator i = siChangedForFileMap.keySet().iterator(); i.hasNext(); ) {
// IPath path = (IPath) i.next();
IFile file = (IFile) i.next();
Integer cmdId = (Integer) siChangedForFileMap.get(file);
if (cmdId != null) {
if (!siChangedForCommandIdList.contains(cmdId)) {
siChangedForCommandIdList.add(cmdId);
}
}
}
}
Collections.sort(siChangedForCommandIdList);
for (Iterator i = siChangedForCommandIdList.iterator(); i.hasNext(); ) {
Integer cmdId = (Integer) i.next();
CCommandDSC command = (CCommandDSC) sid.commandIdCommandMap.get(cmdId);
rv.add(command);
}
}
}
}
return rv; return rv;
} }
@ -568,21 +592,23 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
*/ */
public void deleteAll(IResource resource) { public void deleteAll(IResource resource) {
if (resource.equals(project)) { if (resource.equals(project)) {
// siChangedForFileList = new ArrayList(); synchronized (fLock) {
siChangedForFileMap.clear(); // siChangedForFileList = new ArrayList();
Set changedFiles = sid.fileToCommandIdMap.keySet(); siChangedForFileMap.clear();
for (Iterator i = changedFiles.iterator(); i.hasNext(); ) { Set<IFile> changedFiles = sid.fileToCommandIdMap.keySet();
IFile file = (IFile) i.next(); for (Iterator<IFile> i = changedFiles.iterator(); i.hasNext(); ) {
// IPath path = file.getFullPath(); IFile file = i.next();
// siChangedForFileList.add(path); // IPath path = file.getFullPath();
siChangedForFileMap.put(file, null); // siChangedForFileList.add(path);
} siChangedForFileMap.put(file, null);
}
sid = new ScannerInfoData(); sid = new ScannerInfoData();
psi = null; psi = null;
commandIdCounter = 0; commandIdCounter = 0;
freeCommandIdPool.clear(); freeCommandIdPool.clear();
}
} }
} }
@ -591,7 +617,7 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* *
* @author vhirsl * @author vhirsl
*/ */
public class PerFileDiscoveredPathInfo implements IPerFileDiscoveredPathInfo2 { private class PerFileDiscoveredPathInfo implements IPerFileDiscoveredPathInfo2 {
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getProject() * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getProject()
*/ */
@ -603,122 +629,140 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths() * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths()
*/ */
public IPath[] getIncludePaths() { public IPath[] getIncludePaths() {
// return new IPath[0]; final IPath[] includepaths;
IPath[] includepaths = getAllIncludePaths(INCLUDE_PATH); final IPath[] quotepaths;
IPath[] quotepaths = getAllIncludePaths(QUOTE_INCLUDE_PATH); synchronized (PerFileSICollector.this.fLock) {
// return new IPath[0];
includepaths = getAllIncludePaths(INCLUDE_PATH);
quotepaths = getAllIncludePaths(QUOTE_INCLUDE_PATH);
}
if (quotepaths == null || quotepaths.length == 0) { if (quotepaths == null || quotepaths.length == 0) {
return includepaths; return includepaths;
} }
if (includepaths == null || includepaths.length == 0) { if (includepaths == null || includepaths.length == 0) {
return quotepaths; return quotepaths;
} }
ArrayList result = new ArrayList(includepaths.length + quotepaths.length); ArrayList<IPath> result = new ArrayList<IPath>(includepaths.length + quotepaths.length);
result.addAll(Arrays.asList(includepaths)); result.addAll(Arrays.asList(includepaths));
result.addAll(Arrays.asList(quotepaths)); result.addAll(Arrays.asList(quotepaths));
return (IPath[])result.toArray(new IPath[result.size()]); return result.toArray(new IPath[result.size()]);
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols() * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols()
*/ */
public Map getSymbols() { public Map<String, String> getSymbols() {
// return new HashMap(); // return new HashMap();
return getAllSymbols(); synchronized (PerFileSICollector.this.fLock) {
return getAllSymbols();
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths(org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludePaths(org.eclipse.core.runtime.IPath)
*/ */
public IPath[] getIncludePaths(IPath path) { public IPath[] getIncludePaths(IPath path) {
// get the command synchronized (PerFileSICollector.this.fLock) {
CCommandDSC cmd = getCommand(path); // get the command
if (cmd != null && cmd.isDiscovered()) { CCommandDSC cmd = getCommand(path);
return stringListToPathArray(cmd.getIncludes()); if (cmd != null && cmd.isDiscovered()) {
} return stringListToPathArray(cmd.getIncludes());
// use project scope scanner info }
if (psi == null) { // use project scope scanner info
generateProjectScannerInfo(); if (psi == null) {
} generateProjectScannerInfo();
return psi.includePaths; }
return psi.includePaths;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getQuoteIncludePaths(org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getQuoteIncludePaths(org.eclipse.core.runtime.IPath)
*/ */
public IPath[] getQuoteIncludePaths(IPath path) { public IPath[] getQuoteIncludePaths(IPath path) {
// get the command synchronized (PerFileSICollector.this.fLock) {
CCommandDSC cmd = getCommand(path); // get the command
if (cmd != null && cmd.isDiscovered()) { CCommandDSC cmd = getCommand(path);
return stringListToPathArray(cmd.getQuoteIncludes()); if (cmd != null && cmd.isDiscovered()) {
} return stringListToPathArray(cmd.getQuoteIncludes());
// use project scope scanner info }
if (psi == null) { // use project scope scanner info
generateProjectScannerInfo(); if (psi == null) {
} generateProjectScannerInfo();
return psi.quoteIncludePaths; }
return psi.quoteIncludePaths;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols(org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getSymbols(org.eclipse.core.runtime.IPath)
*/ */
public Map getSymbols(IPath path) { public Map<String, String> getSymbols(IPath path) {
// get the command synchronized (PerFileSICollector.this.fLock) {
CCommandDSC cmd = getCommand(path); // get the command
if (cmd != null && cmd.isDiscovered()) { CCommandDSC cmd = getCommand(path);
List symbols = cmd.getSymbols(); if (cmd != null && cmd.isDiscovered()) {
Map definedSymbols = new HashMap(symbols.size()); List symbols = cmd.getSymbols();
for (Iterator i = symbols.iterator(); i.hasNext(); ) { Map<String, String> definedSymbols = new HashMap<String, String>(symbols.size());
String symbol = (String) i.next(); for (Iterator i = symbols.iterator(); i.hasNext(); ) {
String key = ScannerConfigUtil.getSymbolKey(symbol); String symbol = (String) i.next();
String value = ScannerConfigUtil.getSymbolValue(symbol); String key = ScannerConfigUtil.getSymbolKey(symbol);
definedSymbols.put(key, value); String value = ScannerConfigUtil.getSymbolValue(symbol);
} definedSymbols.put(key, value);
return definedSymbols; }
} return definedSymbols;
// use project scope scanner info }
if (psi == null) { // use project scope scanner info
generateProjectScannerInfo(); if (psi == null) {
} generateProjectScannerInfo();
return psi.definedSymbols; }
return psi.definedSymbols;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludeFiles(org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IDiscoveredPathInfo#getIncludeFiles(org.eclipse.core.runtime.IPath)
*/ */
public IPath[] getIncludeFiles(IPath path) { public IPath[] getIncludeFiles(IPath path) {
// get the command synchronized (PerFileSICollector.this.fLock) {
CCommandDSC cmd = getCommand(path); // get the command
if (cmd != null) { CCommandDSC cmd = getCommand(path);
return stringListToPathArray(cmd.getIncludeFile()); if (cmd != null) {
} return stringListToPathArray(cmd.getIncludeFile());
// use project scope scanner info }
if (psi == null) { // use project scope scanner info
generateProjectScannerInfo(); if (psi == null) {
} generateProjectScannerInfo();
return psi.includeFiles; }
return psi.includeFiles;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getMacroFiles(org.eclipse.core.runtime.IPath) * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getMacroFiles(org.eclipse.core.runtime.IPath)
*/ */
public IPath[] getMacroFiles(IPath path) { public IPath[] getMacroFiles(IPath path) {
// get the command synchronized (PerFileSICollector.this.fLock) {
CCommandDSC cmd = getCommand(path); // get the command
if (cmd != null) { CCommandDSC cmd = getCommand(path);
return stringListToPathArray(cmd.getImacrosFile()); if (cmd != null) {
} return stringListToPathArray(cmd.getImacrosFile());
// use project scope scanner info }
if (psi == null) { // use project scope scanner info
generateProjectScannerInfo(); if (psi == null) {
} generateProjectScannerInfo();
return psi.macrosFiles; }
return psi.macrosFiles;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getSerializable() * @see org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager.IPerFileDiscoveredPathInfo#getSerializable()
*/ */
public IDiscoveredScannerInfoSerializable getSerializable() { public IDiscoveredScannerInfoSerializable getSerializable() {
return sid; synchronized (PerFileSICollector.this.fLock) {
return sid;
}
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -732,21 +776,26 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
rc = (getCommand((IFile)resource) == null); rc = (getCommand((IFile)resource) == null);
} }
else if (resource instanceof IProject) { else if (resource instanceof IProject) {
rc = (psi == null || psi.isEmpty()); synchronized (PerFileSICollector.this.fLock) {
rc = (psi == null || psi.isEmpty());
}
} }
} }
return rc; return rc;
} }
public Map getPathInfoMap() { public Map<IResource, PathInfo> getPathInfoMap() {
//TODO: do we need to cache this? synchronized (PerFileSICollector.this.fLock) {
return calculatePathInfoMap(); //TODO: do we need to cache this?
return calculatePathInfoMap();
}
} }
} }
private Map calculatePathInfoMap(){ private Map<IResource, PathInfo> calculatePathInfoMap(){
Map map = new HashMap(sid.fileToCommandIdMap.size() + 1); assert Thread.holdsLock(fLock);
Map<IResource, PathInfo> map = new HashMap<IResource, PathInfo>(sid.fileToCommandIdMap.size() + 1);
Map.Entry entry; Map.Entry entry;
IFile file; IFile file;
CCommandDSC cmd; CCommandDSC cmd;
@ -755,7 +804,7 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
entry = (Map.Entry)iter.next(); entry = (Map.Entry)iter.next();
file = (IFile)entry.getKey(); file = (IFile)entry.getKey();
if(file != null){ if(file != null){
cmd = (CCommandDSC)sid.commandIdCommandMap.get(entry.getValue()); cmd = sid.commandIdCommandMap.get(entry.getValue());
if(cmd != null){ if(cmd != null){
fpi = createFilePathInfo(cmd); fpi = createFilePathInfo(cmd);
map.put(file, fpi); map.put(file, fpi);
@ -775,13 +824,13 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
return map; return map;
} }
private PathInfo createFilePathInfo(CCommandDSC cmd){ private static PathInfo createFilePathInfo(CCommandDSC cmd){
IPath[] includes = stringListToPathArray(cmd.getIncludes()); IPath[] includes = stringListToPathArray(cmd.getIncludes());
IPath[] quotedIncludes = stringListToPathArray(cmd.getQuoteIncludes()); IPath[] quotedIncludes = stringListToPathArray(cmd.getQuoteIncludes());
IPath[] incFiles = stringListToPathArray(cmd.getIncludeFile()); IPath[] incFiles = stringListToPathArray(cmd.getIncludeFile());
IPath[] macroFiles = stringListToPathArray(cmd.getImacrosFile()); IPath[] macroFiles = stringListToPathArray(cmd.getImacrosFile());
List symbols = cmd.getSymbols(); List symbols = cmd.getSymbols();
Map definedSymbols = new HashMap(symbols.size()); Map<String, String> definedSymbols = new HashMap<String, String>(symbols.size());
for (Iterator i = symbols.iterator(); i.hasNext(); ) { for (Iterator i = symbols.iterator(); i.hasNext(); ) {
String symbol = (String) i.next(); String symbol = (String) i.next();
String key = ScannerConfigUtil.getSymbolKey(symbol); String key = ScannerConfigUtil.getSymbolKey(symbol);
@ -790,7 +839,6 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
} }
return new PathInfo(includes, quotedIncludes, definedSymbols, incFiles, macroFiles); return new PathInfo(includes, quotedIncludes, definedSymbols, incFiles, macroFiles);
} }
/** /**
@ -810,10 +858,10 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
private CCommandDSC getCommand(IFile file) { private CCommandDSC getCommand(IFile file) {
CCommandDSC cmd = null; CCommandDSC cmd = null;
if (file != null) { if (file != null) {
Integer cmdId = (Integer) sid.fileToCommandIdMap.get(file); Integer cmdId = sid.fileToCommandIdMap.get(file);
if (cmdId != null) { if (cmdId != null) {
// get the command // get the command
cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); cmd = sid.commandIdCommandMap.get(cmdId);
} }
} }
return cmd; return cmd;
@ -829,12 +877,12 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @return list of IPath(s). * @return list of IPath(s).
*/ */
private IPath[] getAllIncludePaths(int type) { private IPath[] getAllIncludePaths(int type) {
List allIncludes = new ArrayList(); List<String> allIncludes = new ArrayList<String>();
for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) {
Integer cmdId = (Integer) i.next(); Integer cmdId = i.next();
CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); CCommandDSC cmd = sid.commandIdCommandMap.get(cmdId);
if (cmd.isDiscovered()) { if (cmd.isDiscovered()) {
List discovered = null; List<String> discovered = null;
switch (type) { switch (type) {
case INCLUDE_PATH: case INCLUDE_PATH:
discovered = cmd.getIncludes(); discovered = cmd.getIncludes();
@ -849,8 +897,8 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
discovered = cmd.getImacrosFile(); discovered = cmd.getImacrosFile();
break; break;
} }
for (Iterator j = discovered.iterator(); j.hasNext(); ) { for (Iterator<String> j = discovered.iterator(); j.hasNext(); ) {
String include = (String) j.next(); String include = j.next();
// the following line degrades perfomance // the following line degrades perfomance
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=189127 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=189127
// it is not necessary for renaming projects anyway // it is not necessary for renaming projects anyway
@ -869,25 +917,26 @@ public class PerFileSICollector implements IScannerInfoCollector3, IScannerInfoC
* @param allIncludes * @param allIncludes
* @return * @return
*/ */
private IPath[] stringListToPathArray(List discovered) { private static IPath[] stringListToPathArray(List<String> discovered) {
List allIncludes = new ArrayList(discovered.size()); List<Path> allIncludes = new ArrayList<Path>(discovered.size());
for (Iterator j = discovered.iterator(); j.hasNext(); ) { for (Iterator<String> j = discovered.iterator(); j.hasNext(); ) {
String include = (String) j.next(); String include = j.next();
if (!allIncludes.contains(include)) { if (!allIncludes.contains(include)) {
allIncludes.add(new Path(include)); allIncludes.add(new Path(include));
} }
} }
return (IPath[])allIncludes.toArray(new IPath[allIncludes.size()]); return allIncludes.toArray(new IPath[allIncludes.size()]);
} }
/** /**
* @return * @return
*/ */
private Map getAllSymbols() { private Map<String, String> getAllSymbols() {
Map symbols = new HashMap(); assert Thread.holdsLock(fLock);
for (Iterator i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) { Map<String, String> symbols = new HashMap<String, String>();
Integer cmdId = (Integer) i.next(); for (Iterator<Integer> i = sid.commandIdCommandMap.keySet().iterator(); i.hasNext(); ) {
CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(cmdId); Integer cmdId = i.next();
CCommandDSC cmd = sid.commandIdCommandMap.get(cmdId);
if (cmd.isDiscovered()) { if (cmd.isDiscovered()) {
List discovered = cmd.getSymbols(); List discovered = cmd.getSymbols();
for (Iterator j = discovered.iterator(); j.hasNext(); ) { for (Iterator j = discovered.iterator(); j.hasNext(); ) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -11,6 +11,7 @@
package org.eclipse.cdt.make.internal.core.scannerconfig2; package org.eclipse.cdt.make.internal.core.scannerconfig2;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -31,28 +32,26 @@ import org.eclipse.core.runtime.Preferences;
* *
* @author vhirsl * @author vhirsl
*/ */
public class ScannerConfigProfileManager { public final class ScannerConfigProfileManager {
public static final String SI_PROFILE_SIMPLE_ID = "ScannerConfigurationDiscoveryProfile"; //$NON-NLS-1$ public static final String SI_PROFILE_SIMPLE_ID = "ScannerConfigurationDiscoveryProfile"; //$NON-NLS-1$
public static final String PER_PROJECT_PROFILE_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCStandardMakePerProjectProfile"; //$NON-NLS-1$ public static final String PER_PROJECT_PROFILE_ID = MakeCorePlugin.getUniqueIdentifier() + ".GCCStandardMakePerProjectProfile"; //$NON-NLS-1$
public static final String DEFAULT_SI_PROFILE_ID = PER_PROJECT_PROFILE_ID; public static final String DEFAULT_SI_PROFILE_ID = PER_PROJECT_PROFILE_ID;
public static final String NULL_PROFILE_ID = "";//$NON-NLS-1$ public static final String NULL_PROFILE_ID = "";//$NON-NLS-1$
private Map projectToProfileInstanceMap; private final Map<IProject, Map<InfoContext, Object>> projectToProfileInstanceMap;
private List profileIds; private List<String> profileIds;
private List contextAwareProfileIds; private List<String> contextAwareProfileIds;
private final Object fLock = new Object();
/** /**
* Singleton pattern * Singleton pattern
*/ */
private ScannerConfigProfileManager() { private ScannerConfigProfileManager() {
projectToProfileInstanceMap = new HashMap(); projectToProfileInstanceMap = new HashMap<IProject, Map<InfoContext, Object>>();
} }
private static ScannerConfigProfileManager instance = null; private static final ScannerConfigProfileManager instance = new ScannerConfigProfileManager();
public static ScannerConfigProfileManager getInstance() { public static ScannerConfigProfileManager getInstance() {
if (instance == null) {
instance = new ScannerConfigProfileManager();
}
return instance; return instance;
} }
@ -85,17 +84,21 @@ public class ScannerConfigProfileManager {
getProfileMap(project, true).put(context, profile); getProfileMap(project, true).put(context, profile);
} }
private Map getProfileMap(IProject project, boolean create){ private Map<InfoContext, Object> getProfileMap(IProject project, boolean create){
Map map = (Map)projectToProfileInstanceMap.get(project); synchronized (fLock) {
if(map == null && create){ Map<InfoContext, Object> map = projectToProfileInstanceMap.get(project);
map = new HashMap(); if(map == null && create){
projectToProfileInstanceMap.put(project, map); map = new HashMap<InfoContext, Object>();
projectToProfileInstanceMap.put(project, map);
}
return Collections.synchronizedMap(map);
} }
return map;
} }
public void handleProjectRemoved(IProject project){ public void handleProjectRemoved(IProject project){
projectToProfileInstanceMap.remove(project); synchronized (fLock) {
projectToProfileInstanceMap.remove(project);
}
} }
/** /**
@ -113,14 +116,16 @@ public class ScannerConfigProfileManager {
if (profileId == NULL_PROFILE_ID) { if (profileId == NULL_PROFILE_ID) {
profileId = getProfileId(project, context); profileId = getProfileId(project, context);
} }
// is the project's profile already loaded? synchronized (fLock) {
Map map = getProfileMap(project, true); // is the project's profile already loaded?
SCProfileInstance profileInstance = (SCProfileInstance) map.get(context); Map<InfoContext, Object> map = getProfileMap(project, true);
if (profileInstance == null || !profileInstance.getProfile().getId().equals(profileId)) { SCProfileInstance profileInstance = (SCProfileInstance) map.get(context);
profileInstance = new SCProfileInstance(project, context, getSCProfileConfiguration(profileId)); if (profileInstance == null || !profileInstance.getProfile().getId().equals(profileId)) {
map.put(context, profileInstance); profileInstance = new SCProfileInstance(project, context, getSCProfileConfiguration(profileId));
} map.put(context, profileInstance);
return profileInstance; }
return profileInstance;
}
} }
/** /**
@ -147,20 +152,24 @@ public class ScannerConfigProfileManager {
/** /**
* @return * @return
*/ */
public List getProfileIds() { public List<String> getProfileIds() {
if (profileIds == null) { if (profileIds == null) {
profileIds = new ArrayList(); synchronized (fLock) {
IExtensionPoint extension = Platform.getExtensionRegistry(). if (profileIds == null) {
getExtensionPoint(MakeCorePlugin.PLUGIN_ID, ScannerConfigProfileManager.SI_PROFILE_SIMPLE_ID); profileIds = new ArrayList<String>();
if (extension != null) { IExtensionPoint extension = Platform.getExtensionRegistry().
IExtension[] extensions = extension.getExtensions(); getExtensionPoint(MakeCorePlugin.PLUGIN_ID, ScannerConfigProfileManager.SI_PROFILE_SIMPLE_ID);
for (int i = 0; i < extensions.length; ++i) { if (extension != null) {
String rProfileId = extensions[i].getUniqueIdentifier(); IExtension[] extensions = extension.getExtensions();
profileIds.add(rProfileId); for (int i = 0; i < extensions.length; ++i) {
String rProfileId = extensions[i].getUniqueIdentifier();
profileIds.add(rProfileId);
}
}
} }
} }
} }
return profileIds; return Collections.unmodifiableList(profileIds);
} }
/** /**
@ -168,23 +177,26 @@ public class ScannerConfigProfileManager {
* @param context * @param context
* @return * @return
*/ */
public List getProfileIds(InfoContext context){ public List<String> getProfileIds(InfoContext context){
if(context.isDefaultContext() || context.getProject() == null) if(context.isDefaultContext() || context.getProject() == null)
return getProfileIds(); return getProfileIds();
if(contextAwareProfileIds == null){ if(contextAwareProfileIds == null){
contextAwareProfileIds = new ArrayList(); synchronized (fLock) {
List all = getProfileIds(); if(contextAwareProfileIds == null){
contextAwareProfileIds = new ArrayList<String>();
List<String> all = getProfileIds();
for(int i = 0; i < all.size(); i++){ for(int i = 0; i < all.size(); i++){
String id = (String)all.get(i); String id = all.get(i);
ScannerConfigProfile profile = getSCProfileConfiguration(id); ScannerConfigProfile profile = getSCProfileConfiguration(id);
if(profile.supportsContext()) if(profile.supportsContext())
contextAwareProfileIds.add(id); contextAwareProfileIds.add(id);
}
}
} }
} }
return Collections.unmodifiableList(contextAwareProfileIds);
return contextAwareProfileIds;
} }
/** /**