1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-06 08:35:26 +02:00

Bug 387507 - PDOMManager.joinIndexer() can wrongly return false

Change-Id: Iebe3bb8840ea4b27bb2624a0526cf0f0f6ac0669
Reviewed-on: https://git.eclipse.org/r/7281
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
John Cortell 2012-08-17 20:04:29 -05:00 committed by Sergey Prigogin
parent ae8af8e02f
commit e98ee53a9f

View file

@ -149,12 +149,12 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private final PDOMIndexerJob fIndexerJob; private final PDOMIndexerJob fIndexerJob;
private IPDOMIndexerTask fCurrentTask; private IPDOMIndexerTask fCurrentTask;
private int fSourceCount, fHeaderCount, fTickCount; private int fSourceCount, fHeaderCount, fTickCount;
private final ArrayDeque<Runnable> fChangeEvents= new ArrayDeque<Runnable>(); private final ArrayDeque<Runnable> fChangeEvents= new ArrayDeque<Runnable>();
private final Job fNotificationJob; private final Job fNotificationJob;
private final AtomicMultiSet<IIndexFileLocation> fFilesIndexedUnconditionlly= new AtomicMultiSet<IIndexFileLocation>(); private final AtomicMultiSet<IIndexFileLocation> fFilesIndexedUnconditionlly= new AtomicMultiSet<IIndexFileLocation>();
/** /**
* Stores mapping from pdom to project, used to serialize creation of new pdoms. * Stores mapping from pdom to project, used to serialize creation of new pdoms.
*/ */
@ -162,7 +162,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private Map<File, ICProject> fFileToProject= new HashMap<File, ICProject>(); private Map<File, ICProject> fFileToProject= new HashMap<File, ICProject>();
private ListenerList fChangeListeners= new ListenerList(); private ListenerList fChangeListeners= new ListenerList();
private ListenerList fStateListeners= new ListenerList(); private ListenerList fStateListeners= new ListenerList();
private IndexChangeEvent fIndexChangeEvent= new IndexChangeEvent(); private IndexChangeEvent fIndexChangeEvent= new IndexChangeEvent();
private IndexerStateEvent fIndexerStateEvent= new IndexerStateEvent(); private IndexerStateEvent fIndexerStateEvent= new IndexerStateEvent();
@ -172,17 +172,17 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private final ICProjectDescriptionListener fProjectDescriptionListener; private final ICProjectDescriptionListener fProjectDescriptionListener;
private final JobChangeListener fJobChangeListener; private final JobChangeListener fJobChangeListener;
private final IPreferenceChangeListener fPreferenceChangeListener; private final IPreferenceChangeListener fPreferenceChangeListener;
private IndexFactory fIndexFactory= new IndexFactory(this); private IndexFactory fIndexFactory= new IndexFactory(this);
private IndexProviderManager fIndexProviderManager = new IndexProviderManager(); private IndexProviderManager fIndexProviderManager = new IndexProviderManager();
/** /**
* Serializes creation of new indexer, when acquiring the lock you are * Serializes creation of new indexer, when acquiring the lock you are
* not allowed to hold a lock on fPDOMs. * not allowed to hold a lock on fPDOMs.
*/ */
private Map<ICProject, IndexUpdatePolicy> fUpdatePolicies= new HashMap<ICProject, IndexUpdatePolicy>(); private Map<ICProject, IndexUpdatePolicy> fUpdatePolicies= new HashMap<ICProject, IndexUpdatePolicy>();
private Set<String> fClosingProjects= new HashSet<String>(); private Set<String> fClosingProjects= new HashSet<String>();
private Map<IProject, PCL> fPrefListeners= new HashMap<IProject, PCL>(); private Map<IProject, PCL> fPrefListeners= new HashMap<IProject, PCL>();
private List<IndexerSetupParticipant> fSetupParticipants= new ArrayList<IndexerSetupParticipant>(); private List<IndexerSetupParticipant> fSetupParticipants= new ArrayList<IndexerSetupParticipant>();
private Set<ICProject> fPostponedProjects= new HashSet<ICProject>(); private Set<ICProject> fPostponedProjects= new HashSet<ICProject>();
@ -190,7 +190,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private boolean fInShutDown; private boolean fInShutDown;
boolean fTraceIndexerSetup; boolean fTraceIndexerSetup;
public PDOMManager() { public PDOMManager() {
PDOM.sDEBUG_LOCKS= "true".equals(Platform.getDebugOption(CCorePlugin.PLUGIN_ID + "/debug/index/locks")); //$NON-NLS-1$//$NON-NLS-2$ PDOM.sDEBUG_LOCKS= "true".equals(Platform.getDebugOption(CCorePlugin.PLUGIN_ID + "/debug/index/locks")); //$NON-NLS-1$//$NON-NLS-2$
addIndexerSetupParticipant(new WaitForRefreshJobs()); addIndexerSetupParticipant(new WaitForRefreshJobs());
@ -206,7 +206,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fIndexerJob= new PDOMIndexerJob(this); fIndexerJob= new PDOMIndexerJob(this);
fNotificationJob= createNotifyJob(); fNotificationJob= createNotifyJob();
} }
public Job startup() { public Job startup() {
fInShutDown= false; fInShutDown= false;
Job postStartupJob= new Job(CCorePlugin.getResourceString("CCorePlugin.startupJob")) { //$NON-NLS-1$ Job postStartupJob= new Job(CCorePlugin.getResourceString("CCorePlugin.startupJob")) { //$NON-NLS-1$
@ -221,10 +221,10 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
}; };
postStartupJob.setSystem(true); postStartupJob.setSystem(true);
return postStartupJob; return postStartupJob;
} }
/** /**
* Called from a job after plugin start. * Called from a job after plugin start.
*/ */
protected void postStartup() { protected void postStartup() {
@ -236,7 +236,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
adjustCacheSize(); adjustCacheSize();
updatePathCanonicalizationStrategy(); updatePathCanonicalizationStrategy();
fIndexProviderManager.startup(); fIndexProviderManager.startup();
fTraceIndexerSetup= String.valueOf(true).equals(Platform.getDebugOption(TRACE_INDEXER_SETUP)); fTraceIndexerSetup= String.valueOf(true).equals(Platform.getDebugOption(TRACE_INDEXER_SETUP));
final CoreModel model = CoreModel.getDefault(); final CoreModel model = CoreModel.getDefault();
ResourcesPlugin.getWorkspace().addResourceChangeListener(fCModelListener, IResourceChangeEvent.POST_BUILD); ResourcesPlugin.getWorkspace().addResourceChangeListener(fCModelListener, IResourceChangeEvent.POST_BUILD);
@ -270,7 +270,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fTaskQueue.clear(); fTaskQueue.clear();
jobToCancel= fIndexerJob; jobToCancel= fIndexerJob;
} }
if (jobToCancel != null) { if (jobToCancel != null) {
assert !Thread.holdsLock(fTaskQueue); assert !Thread.holdsLock(fTaskQueue);
jobToCancel.cancelJobs(null, false); jobToCancel.cancelJobs(null, false);
@ -292,7 +292,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
reindexAll(); reindexAll();
} }
} }
protected void adjustCacheSize() { protected void adjustCacheSize() {
IPreferencesService prefs = Platform.getPreferencesService(); IPreferencesService prefs = Platform.getPreferencesService();
int cachePct= prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT, 10, null); int cachePct= prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT, 10, null);
@ -315,7 +315,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
/** /**
* Returns the pdom for the project. * Returns the pdom for the project.
* @throws CoreException * @throws CoreException
*/ */
public IPDOM getPDOM(ICProject project) throws CoreException { public IPDOM getPDOM(ICProject project) throws CoreException {
@ -329,9 +329,9 @@ public class PDOMManager implements IWritableIndexManager, IListener {
return pdom; return pdom;
} }
} }
/** /**
* Returns the pdom for the project. The call to the method may cause * Returns the pdom for the project. The call to the method may cause
* opening the database. In case there is a version mismatch the data * opening the database. In case there is a version mismatch the data
* base is cleared, in case it does not exist it is created. In any * base is cleared, in case it does not exist it is created. In any
* case a pdom ready to use is returned. * case a pdom ready to use is returned.
@ -392,7 +392,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
pdom.setASTFilePathResolver(new ProjectIndexerInputAdapter(project, false)); pdom.setASTFilePathResolver(new ProjectIndexerInputAdapter(project, false));
pdom.addListener(this); pdom.addListener(this);
fFileToProject.put(dbFile, project); fFileToProject.put(dbFile, project);
fProjectToPDOM.put(rproject, pdom); fProjectToPDOM.put(rproject, pdom);
if (pdomProxy instanceof PDOMProxy) { if (pdomProxy instanceof PDOMProxy) {
@ -440,7 +440,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public void setDefaultIndexerId(String indexerId) { public void setDefaultIndexerId(String indexerId) {
IndexerPreferences.setDefaultIndexerId(indexerId); IndexerPreferences.setDefaultIndexerId(indexerId);
} }
@Override @Override
public String getIndexerId(ICProject project) { public String getIndexerId(ICProject project) {
IProject prj= project != null ? project.getProject() : null; IProject prj= project != null ? project.getProject() : null;
@ -453,7 +453,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
IndexerPreferences.set(prj, IndexerPreferences.KEY_INDEXER_ID, indexerId); IndexerPreferences.set(prj, IndexerPreferences.KEY_INDEXER_ID, indexerId);
CCoreInternals.savePreferences(prj, IndexerPreferences.getScope(prj) == IndexerPreferences.SCOPE_PROJECT_SHARED); CCoreInternals.savePreferences(prj, IndexerPreferences.getScope(prj) == IndexerPreferences.SCOPE_PROJECT_SHARED);
} }
protected void onPreferenceChange(ICProject cproject, PreferenceChangeEvent event) { protected void onPreferenceChange(ICProject cproject, PreferenceChangeEvent event) {
if (IndexerPreferences.KEY_UPDATE_POLICY.equals(event.getKey())) { if (IndexerPreferences.KEY_UPDATE_POLICY.equals(event.getKey())) {
changeUpdatePolicy(cproject); changeUpdatePolicy(cproject);
@ -484,17 +484,17 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private void changeIndexer(ICProject cproject) throws CoreException { private void changeIndexer(ICProject cproject) throws CoreException {
assert !Thread.holdsLock(fProjectToPDOM); assert !Thread.holdsLock(fProjectToPDOM);
// if there is no indexer, don't touch the preferences. // if there is no indexer, don't touch the preferences.
IPDOMIndexer oldIndexer= getIndexer(cproject); IPDOMIndexer oldIndexer= getIndexer(cproject);
if (oldIndexer == null) { if (oldIndexer == null) {
return; return;
} }
IProject prj= cproject.getProject(); IProject prj= cproject.getProject();
String newid= IndexerPreferences.get(prj, IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_NO_INDEXER); String newid= IndexerPreferences.get(prj, IndexerPreferences.KEY_INDEXER_ID, IPDOMManager.ID_NO_INDEXER);
Properties props= IndexerPreferences.getProperties(prj); Properties props= IndexerPreferences.getProperties(prj);
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
if (fClosingProjects.contains(prj.getName())) { if (fClosingProjects.contains(prj.getName())) {
return; return;
@ -519,7 +519,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
enqueue(new PDOMRebuildTask(indexer)); enqueue(new PDOMRebuildTask(indexer));
} }
} }
if (oldIndexer != null) { if (oldIndexer != null) {
stopIndexer(oldIndexer); stopIndexer(oldIndexer);
} }
@ -546,24 +546,24 @@ public class PDOMManager implements IWritableIndexManager, IListener {
void createIndexer(ICProject project, IProgressMonitor pm) throws InterruptedException { void createIndexer(ICProject project, IProgressMonitor pm) throws InterruptedException {
final IProject prj= project.getProject(); final IProject prj= project.getProject();
final String name = prj.getName(); final String name = prj.getName();
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Creation for project " + name); //$NON-NLS-1$ System.out.println("Indexer: Creation for project " + name); //$NON-NLS-1$
assert !Thread.holdsLock(fProjectToPDOM); assert !Thread.holdsLock(fProjectToPDOM);
try { try {
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
if (fClosingProjects.contains(name)) { if (fClosingProjects.contains(name)) {
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Aborting setup (1) for closing project " + name + " [1]"); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println("Indexer: Aborting setup (1) for closing project " + name + " [1]"); //$NON-NLS-1$ //$NON-NLS-2$
return; return;
} }
WritablePDOM pdom= getOrCreatePDOM(project); WritablePDOM pdom= getOrCreatePDOM(project);
Properties props= IndexerPreferences.getProperties(prj); Properties props= IndexerPreferences.getProperties(prj);
IPDOMIndexer indexer= newIndexer(getIndexerId(project), props); IPDOMIndexer indexer= newIndexer(getIndexerId(project), props);
IndexUpdatePolicy policy= createPolicy(project); IndexUpdatePolicy policy= createPolicy(project);
boolean rebuild= boolean rebuild=
pdom.isClearedBecauseOfVersionMismatch() || pdom.isClearedBecauseOfVersionMismatch() ||
pdom.isCreatedFromScratch() || pdom.isCreatedFromScratch() ||
policy.isInitialRebuildRequested(); policy.isInitialRebuildRequested();
@ -591,7 +591,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
pdom.releaseReadLock(); pdom.releaseReadLock();
} }
if (resume) { if (resume) {
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Resuming for project " + name); //$NON-NLS-1$ System.out.println("Indexer: Resuming for project " + name); //$NON-NLS-1$
enqueue(new PDOMUpdateTask(indexer, enqueue(new PDOMUpdateTask(indexer,
@ -608,7 +608,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
if (fClosingProjects.contains(name)) { if (fClosingProjects.contains(name)) {
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Aborting setup for closing project " + name + " [2]"); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println("Indexer: Aborting setup for closing project " + name + " [2]"); //$NON-NLS-1$ //$NON-NLS-2$
return; return;
} }
@ -623,13 +623,13 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (policy.isAutomatic() || policy.isInitialRebuildRequested()) { if (policy.isAutomatic() || policy.isInitialRebuildRequested()) {
policy.clearInitialFlags(); policy.clearInitialFlags();
if (operation.wasSuccessful()) { if (operation.wasSuccessful()) {
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Imported shared index for project " + name); //$NON-NLS-1$ System.out.println("Indexer: Imported shared index for project " + name); //$NON-NLS-1$
task= new PDOMUpdateTask(indexer, task= new PDOMUpdateTask(indexer,
IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONTENTS_HASH); IIndexManager.UPDATE_CHECK_TIMESTAMPS | IIndexManager.UPDATE_CHECK_CONTENTS_HASH);
} else { } else {
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Rebuiding for project " + name); //$NON-NLS-1$ System.out.println("Indexer: Rebuiding for project " + name); //$NON-NLS-1$
task= new PDOMRebuildTask(indexer); task= new PDOMRebuildTask(indexer);
} }
enqueue(task); enqueue(task);
@ -642,7 +642,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
} }
} }
private IPDOMIndexer newIndexer(String indexerId, Properties props) throws CoreException { private IPDOMIndexer newIndexer(String indexerId, Properties props) throws CoreException {
IPDOMIndexer indexer = null; IPDOMIndexer indexer = null;
// Look up in extension point // Look up in extension point
@ -656,14 +656,14 @@ public class PDOMManager implements IWritableIndexManager, IListener {
indexer.setProperties(props); indexer.setProperties(props);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
break; break;
} }
} }
} }
// Unknown index, default to the null one // Unknown index, default to the null one
if (indexer == null) if (indexer == null)
indexer = new PDOMNullIndexer(); indexer = new PDOMNullIndexer();
return indexer; return indexer;
@ -683,7 +683,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fIndexerJob.schedule(); fIndexerJob.schedule();
} }
} }
IPDOMIndexerTask getNextTask() { IPDOMIndexerTask getNextTask() {
IPDOMIndexerTask result= null; IPDOMIndexerTask result= null;
synchronized (fTaskQueue) { synchronized (fTaskQueue) {
@ -703,7 +703,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
return result; return result;
} }
void cancelledIndexerJob(boolean byManager) { void cancelledIndexerJob(boolean byManager) {
synchronized (fTaskQueue) { synchronized (fTaskQueue) {
fCurrentTask= null; fCurrentTask= null;
@ -715,7 +715,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
} }
} }
@Override @Override
public boolean isIndexerIdle() { public boolean isIndexerIdle() {
return Job.getJobManager().find(this).length == 0; return Job.getJobManager().find(this).length == 0;
@ -725,19 +725,19 @@ public class PDOMManager implements IWritableIndexManager, IListener {
final String name = cproject.getProject().getName(); final String name = cproject.getProject().getName();
if (fTraceIndexerSetup) { if (fTraceIndexerSetup) {
System.out.println("Indexer: Adding new project " + name); //$NON-NLS-1$ System.out.println("Indexer: Adding new project " + name); //$NON-NLS-1$
} }
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
fClosingProjects.remove(name); fClosingProjects.remove(name);
} }
setupProject(cproject); setupProject(cproject);
} }
void setupProject(final ICProject cproject) { void setupProject(final ICProject cproject) {
if (fInShutDown) if (fInShutDown)
return; return;
synchronized (fProjectQueue) { synchronized (fProjectQueue) {
fProjectQueue.add(cproject); fProjectQueue.add(cproject);
} }
@ -776,7 +776,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) { if (indexer != null && indexer.getID().equals(IPDOMManager.ID_NO_INDEXER)) {
return; return;
} }
if (added.length > 0 || changed.length > 0 || removed.length > 0) { if (added.length > 0 || changed.length > 0 || removed.length > 0) {
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
IndexUpdatePolicy policy= createPolicy(project); IndexUpdatePolicy policy= createPolicy(project);
@ -807,7 +807,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
public void preDeleteProject(ICProject cproject) { public void preDeleteProject(ICProject cproject) {
preRemoveProject(cproject, true); preRemoveProject(cproject, true);
} }
public void preCloseProject(ICProject cproject) { public void preCloseProject(ICProject cproject) {
@ -820,8 +820,8 @@ public class PDOMManager implements IWritableIndexManager, IListener {
final IProject rproject= cproject.getProject(); final IProject rproject= cproject.getProject();
final String name = rproject.getName(); final String name = rproject.getName();
if (fTraceIndexerSetup) if (fTraceIndexerSetup)
System.out.println("Indexer: Removing project " + name + "; delete=" + delete); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println("Indexer: Removing project " + name + "; delete=" + delete); //$NON-NLS-1$ //$NON-NLS-2$
IPDOMIndexer indexer; IPDOMIndexer indexer;
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
@ -868,12 +868,12 @@ public class PDOMManager implements IWritableIndexManager, IListener {
job.setSystem(true); job.setSystem(true);
job.schedule(); job.schedule();
} }
synchronized (fUpdatePolicies) { synchronized (fUpdatePolicies) {
fUpdatePolicies.remove(cproject); fUpdatePolicies.remove(cproject);
} }
} }
void removeProject(ICProject cproject, ICElementDelta delta) { void removeProject(ICProject cproject, ICElementDelta delta) {
synchronized (fProjectToPDOM) { synchronized (fProjectToPDOM) {
IProject rproject= cproject.getProject(); IProject rproject= cproject.getProject();
@ -893,7 +893,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
policy.clearTUs(); policy.clearTUs();
policy.setIndexer(null); policy.setIndexer(null);
} }
} }
} }
cancelIndexerJobs(indexer); cancelIndexerJobs(indexer);
} }
@ -909,13 +909,13 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
jobToCancel= fIndexerJob; jobToCancel= fIndexerJob;
} }
if (jobToCancel != null) { if (jobToCancel != null) {
assert !Thread.holdsLock(fTaskQueue); assert !Thread.holdsLock(fTaskQueue);
jobToCancel.cancelJobs(indexer, true); jobToCancel.cancelJobs(indexer, true);
} }
} }
private void reindexAll() { private void reindexAll() {
ICProject[] cProjects; ICProject[] cProjects;
try { try {
@ -930,7 +930,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
@Override @Override
public void reindex(final ICProject project) { public void reindex(final ICProject project) {
Job job= new Job(Messages.PDOMManager_notifyJob_label) { Job job= new Job(Messages.PDOMManager_notifyJob_label) {
@Override @Override
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
IPDOMIndexer indexer= null; IPDOMIndexer indexer= null;
@ -971,7 +971,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public void removeIndexChangeListener(IIndexChangeListener listener) { public void removeIndexChangeListener(IIndexChangeListener listener) {
fChangeListeners.remove(listener); fChangeListeners.remove(listener);
} }
@Override @Override
public void addIndexerStateListener(IIndexerStateListener listener) { public void addIndexerStateListener(IIndexerStateListener listener) {
fStateListeners.add(listener); fStateListeners.add(listener);
@ -1001,7 +1001,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
notify.setSystem(true); notify.setSystem(true);
return notify; return notify;
} }
private void scheduleNotification(Runnable notify) { private void scheduleNotification(Runnable notify) {
if (fInShutDown) if (fInShutDown)
return; return;
@ -1052,12 +1052,12 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (fChangeListeners.isEmpty()) { if (fChangeListeners.isEmpty()) {
return; return;
} }
ICProject project; ICProject project;
synchronized (fProjectToPDOM) { synchronized (fProjectToPDOM) {
project = fFileToProject.get(pdom.getPath()); project = fFileToProject.get(pdom.getPath());
} }
if (project != null) { if (project != null) {
final ICProject finalProject= project; final ICProject finalProject= project;
Runnable notify= new Runnable() { Runnable notify= new Runnable() {
@ -1088,6 +1088,10 @@ public class PDOMManager implements IWritableIndexManager, IListener {
@Override @Override
public boolean joinIndexer(final int waitMaxMillis, final IProgressMonitor monitor) { public boolean joinIndexer(final int waitMaxMillis, final IProgressMonitor monitor) {
assert monitor != null; assert monitor != null;
long startMillis = System.currentTimeMillis();
// Unfortunately, IJobManager.join() doesn't take a timeout. So, we create a watchdog thread to
// interrupt the call if the indexer job doesn't complete in the alloted time
Thread th= null; Thread th= null;
if (waitMaxMillis != FOREVER) { if (waitMaxMillis != FOREVER) {
final Thread callingThread= Thread.currentThread(); final Thread callingThread= Thread.currentThread();
@ -1112,17 +1116,30 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} catch (OperationCanceledException e) { } catch (OperationCanceledException e) {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
return Job.getJobManager().find(this).length == 0;
// When the indexer job is interrupted, the join() above will throw an exception and that can
// happen slightly before the JobManager updates its job collection. Wait for it.
while (Job.getJobManager().find(this).length != 0) {
if (System.currentTimeMillis() - startMillis > waitMaxMillis) {
return false;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
}
return true;
} finally { } finally {
// Make sure we don't leave the watchdog thread running
if (th != null) { if (th != null) {
th.interrupt(); th.interrupt();
} }
} }
} }
int getMonitorMessage(PDOMIndexerJob job, int currentTicks, int base) { int getMonitorMessage(PDOMIndexerJob job, int currentTicks, int base) {
assert !Thread.holdsLock(fTaskQueue); assert !Thread.holdsLock(fTaskQueue);
int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate; int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate;
String detail= null; String detail= null;
synchronized (fTaskQueue) { synchronized (fTaskQueue) {
@ -1149,14 +1166,14 @@ public class PDOMManager implements IWritableIndexManager, IListener {
detail= PDOMIndexerJob.sMonitorDetail; detail= PDOMIndexerJob.sMonitorDetail;
} }
} }
String msg= MessageFormat.format(Messages.PDOMManager_indexMonitorDetail, new Object[] { String msg= MessageFormat.format(Messages.PDOMManager_indexMonitorDetail, new Object[] {
new Integer(sourceCount), new Integer(sourceEstimate), new Integer(sourceCount), new Integer(sourceEstimate),
new Integer(headerCount)}); new Integer(headerCount)});
if (detail != null) { if (detail != null) {
msg += ": " + detail; //$NON-NLS-1$ msg += ": " + detail; //$NON-NLS-1$
} }
job.subTask(msg); job.subTask(msg);
if (tickCount > 0 && tickCount <= tickEstimate) { if (tickCount > 0 && tickCount <= tickEstimate) {
int newTick= tickCount*base/tickEstimate; int newTick= tickCount*base/tickEstimate;
@ -1192,7 +1209,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public IIndex getIndex(ICProject[] projects, int options) throws CoreException { public IIndex getIndex(ICProject[] projects, int options) throws CoreException {
return fIndexFactory.getIndex(projects, options); return fIndexFactory.getIndex(projects, options);
} }
/** /**
* Exports the project PDOM to the specified location, rewriting locations with * Exports the project PDOM to the specified location, rewriting locations with
* the specified location converter. * the specified location converter.
@ -1228,7 +1245,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
// Overwrite internal location representations. // Overwrite internal location representations.
final WritablePDOM newPDOM = new WritablePDOM(targetLocation, pdom.getLocationConverter(), getLinkageFactories()); final WritablePDOM newPDOM = new WritablePDOM(targetLocation, pdom.getLocationConverter(), getLinkageFactories());
newPDOM.acquireWriteLock(); newPDOM.acquireWriteLock();
try { try {
newPDOM.rewriteLocations(newConverter); newPDOM.rewriteLocations(newConverter);
@ -1248,7 +1265,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
/** /**
* Resets the pdom for the project with the provided stream. * Resets the pdom for the project with the provided stream.
* @throws CoreException * @throws CoreException
* @throws OperationCanceledException in case the thread was interrupted * @throws OperationCanceledException in case the thread was interrupted
* @since 4.0 * @since 4.0
@ -1267,11 +1284,11 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
if (version > PDOM.getMaxSupportedVersion()) { if (version > PDOM.getMaxSupportedVersion()) {
final IStatus status = new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, 0, CCorePlugin.getResourceString("PDOMManager.unsupportedHigherVersion"), null); //$NON-NLS-1$ final IStatus status = new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, 0, CCorePlugin.getResourceString("PDOMManager.unsupportedHigherVersion"), null); //$NON-NLS-1$
throw new CoreException(status); throw new CoreException(status);
} }
if ( !PDOM.isSupportedVersion( version ) ) { if ( !PDOM.isSupportedVersion( version ) ) {
final IStatus status = new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, 0, CCorePlugin.getResourceString("PDOMManager.unsupportedVersion"), null); //$NON-NLS-1$ final IStatus status = new Status(IStatus.WARNING, CCorePlugin.PLUGIN_ID, 0, CCorePlugin.getResourceString("PDOMManager.unsupportedVersion"), null); //$NON-NLS-1$
throw new CoreException(status); throw new CoreException(status);
} }
byte[] buffer= new byte[2048]; byte[] buffer= new byte[2048];
int read; int read;
@ -1281,7 +1298,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} finally { } finally {
out.close(); out.close();
} }
WritablePDOM pdom= (WritablePDOM) getPDOM(project); WritablePDOM pdom= (WritablePDOM) getPDOM(project);
try { try {
pdom.acquireWriteLock(); pdom.acquireWriteLock();
@ -1296,7 +1313,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
pdom.releaseWriteLock(); pdom.releaseWriteLock();
} }
} }
@Override @Override
public void export(ICProject project, String location, int options, IProgressMonitor monitor) throws CoreException { public void export(ICProject project, String location, int options, IProgressMonitor monitor) throws CoreException {
TeamPDOMExportOperation operation= new TeamPDOMExportOperation(project); TeamPDOMExportOperation operation= new TeamPDOMExportOperation(project);
@ -1304,7 +1321,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
operation.setOptions(options); operation.setOptions(options);
operation.run(monitor); operation.run(monitor);
} }
/** /**
* Write metadata appropriate for a project pdom * Write metadata appropriate for a project pdom
* @param pdom the pdom to write to * @param pdom the pdom to write to
@ -1335,7 +1352,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
for (Map.Entry<ICProject, List<ICElement>> entry : projectsToElements.entrySet()) { for (Map.Entry<ICProject, List<ICElement>> entry : projectsToElements.entrySet()) {
ICProject project = entry.getKey(); ICProject project = entry.getKey();
List<ICElement> filesAndFolders = entry.getValue(); List<ICElement> filesAndFolders = entry.getValue();
update(project, filesAndFolders, options); update(project, filesAndFolders, options);
} }
} }
@ -1362,14 +1379,14 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} else if (contains(element, other)) { } else if (contains(element, other)) {
set.set(j, element); set.set(j, element);
continue allElements; continue allElements;
} }
} }
set.add(element); set.add(element);
} }
} }
return result; return result;
} }
private boolean contains(final ICElement a, ICElement b) { private boolean contains(final ICElement a, ICElement b) {
if (a.equals(b)) { if (a.equals(b)) {
return true; return true;
@ -1467,7 +1484,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (fPostponedProjects.contains(project)) { if (fPostponedProjects.contains(project)) {
setupProject(project); setupProject(project);
} }
} }
} }
@Override @Override
@ -1486,7 +1503,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
} }
} }
/** /**
* @param project * @param project
* @return whether the specified project has been registered. If a project has * @return whether the specified project has been registered. If a project has
@ -1496,7 +1513,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public boolean isProjectRegistered(ICProject project) { public boolean isProjectRegistered(ICProject project) {
return getIndexer(project) != null; return getIndexer(project) != null;
} }
/** /**
* @param cproject the project to check * @param cproject the project to check
* @return whether the content in the project fragment of the specified project's index * @return whether the content in the project fragment of the specified project's index
@ -1506,7 +1523,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public boolean isProjectContentSynced(ICProject cproject) throws CoreException { public boolean isProjectContentSynced(ICProject cproject) throws CoreException {
if (!"true".equals(IndexerPreferences.get(cproject.getProject(), IndexerPreferences.KEY_INDEX_ALL_FILES, null))) //$NON-NLS-1$ if (!"true".equals(IndexerPreferences.get(cproject.getProject(), IndexerPreferences.KEY_INDEX_ALL_FILES, null))) //$NON-NLS-1$
return true; // no check performed in this case return true; // no check performed in this case
Set<ITranslationUnit> sources= new HashSet<ITranslationUnit>(); Set<ITranslationUnit> sources= new HashSet<ITranslationUnit>();
cproject.accept(new TranslationUnitCollector(sources, null, new NullProgressMonitor())); cproject.accept(new TranslationUnitCollector(sources, null, new NullProgressMonitor()));
@ -1532,7 +1549,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
return true; return true;
} }
private boolean isSubjectToIndexing(ILanguage language) { private boolean isSubjectToIndexing(ILanguage language) {
final int linkageID=language.getLinkageID(); final int linkageID=language.getLinkageID();
for (int id : IDS_FOR_LINKAGES_TO_INDEX) { for (int id : IDS_FOR_LINKAGES_TO_INDEX) {
@ -1554,7 +1571,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
private static boolean areSynchronized(Set<IIndexFileLocation> trail, IIndex index, IResource resource, IIndexFileLocation location) throws CoreException { private static boolean areSynchronized(Set<IIndexFileLocation> trail, IIndex index, IResource resource, IIndexFileLocation location) throws CoreException {
if (!trail.contains(location)) { if (!trail.contains(location)) {
trail.add(location); trail.add(location);
IIndexFile[] file= index.getFiles(location); IIndexFile[] file= index.getFiles(location);
// pre-includes may be listed twice (191989) // pre-includes may be listed twice (191989)
@ -1580,7 +1597,7 @@ public class PDOMManager implements IWritableIndexManager, IListener {
} }
} }
} }
return true; return true;
} }