diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java index 6cce732b04c..a703bb107f3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndexManager.java @@ -146,7 +146,9 @@ public interface IIndexManager extends IPDOMManager { boolean joinIndexer(int waitMaxMillis, IProgressMonitor monitor); /** - * Checks whether the indexer is currently idle + * Checks whether the indexer is currently idle. The indexer is idle, when there is currently no request + * to update files of an index and no initialization for a project is performed. However, the indexer becomes + * idle, when the setup of a project is postponed (check with {@link #isIndexerSetupPostponed(ICProject)}). */ boolean isIndexerIdle(); @@ -155,6 +157,14 @@ public interface IIndexManager extends IPDOMManager { * @since 4.0 */ boolean isProjectIndexed(ICProject proj); + + /** + * Return whether the indexer-setup for a project is currently postponed. Note, + * that a postponed setup does not prevent the indexer from becoming idle ({@link #isIndexerIdle()}. + * The fact that the indexer-setup for a project is no longer postponed, will be reported using + * {@link IndexerSetupParticipant#onIndexerSetup(ICProject)}. + */ + boolean isIndexerSetupPostponed(ICProject proj); /** * Returns the id of the indexer working on the project. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexerSetupParticipant.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexerSetupParticipant.java index 4979d85d225..570ec8dbed0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexerSetupParticipant.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IndexerSetupParticipant.java @@ -29,7 +29,9 @@ public abstract class IndexerSetupParticipant { * @param project the project for which the indexer is supposed to be initialized. * @return whether or not to proceed with the indexer setup. */ - public abstract boolean postponeIndexerSetup(ICProject project); + public boolean postponeIndexerSetup(ICProject project) { + return false; + } /** * Informs the index manager that this participant no longer needs to postpone the @@ -37,7 +39,14 @@ public abstract class IndexerSetupParticipant { * this may trigger the indexer setup. * @param project the project for which the setup no longer needs to be postponed */ - public void notifyIndexerSetup(ICProject project) { + public final void notifyIndexerSetup(ICProject project) { CCoreInternals.getPDOMManager().notifyIndexerSetup(this, project); } + + /** + * Call-back that tells the implementor that a project has passed all setup participants + * and therefore it is actually initialized. + */ + public void onIndexerSetup(ICProject project) { + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java index 08d9224d4d6..f16e5cd7f6a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/IndexUpdatePolicy.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -30,10 +30,11 @@ public class IndexUpdatePolicy { private final ICProject fCProject; private int fKind; - private HashSet fAdded= new HashSet(); - private HashSet fChanged= new HashSet(); - private HashSet fRemoved= new HashSet(); + private HashSet fAdded= new HashSet(); + private HashSet fChanged= new HashSet(); + private HashSet fRemoved= new HashSet(); private IPDOMIndexer fIndexer; + private boolean fReindexRequested; public IndexUpdatePolicy(ICProject project, int kind) { fCProject= project; @@ -65,15 +66,15 @@ public class IndexUpdatePolicy { } private ITranslationUnit[] getAdded() { - return (ITranslationUnit[]) fAdded.toArray(new ITranslationUnit[fAdded.size()]); + return fAdded.toArray(new ITranslationUnit[fAdded.size()]); } private ITranslationUnit[] getChanged() { - return (ITranslationUnit[]) fChanged.toArray(new ITranslationUnit[fChanged.size()]); + return fChanged.toArray(new ITranslationUnit[fChanged.size()]); } private ITranslationUnit[] getRemoved() { - return (ITranslationUnit[]) fRemoved.toArray(new ITranslationUnit[fRemoved.size()]); + return fRemoved.toArray(new ITranslationUnit[fRemoved.size()]); } public void setIndexer(IPDOMIndexer indexer) { @@ -156,4 +157,16 @@ public class IndexUpdatePolicy { } return task; } + + public void requestInitialReindex() { + fReindexRequested= true; + } + + public void clearInitialFlags() { + fReindexRequested= false; + } + + public boolean isInitialRebuildRequested() { + return fReindexRequested; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index bfae97e6ede..83607099e9b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -479,7 +479,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } - private void registerIndexer(ICProject project, IPDOMIndexer indexer) throws CoreException { + private void registerIndexer(ICProject project, IPDOMIndexer indexer) { assert Thread.holdsLock(fUpdatePolicies); indexer.setProject(project); registerPreferenceListener(project); @@ -505,10 +505,12 @@ public class PDOMManager implements IWritableIndexManager, IListener { WritablePDOM pdom= getOrCreatePDOM(project); Properties props= IndexerPreferences.getProperties(prj); IPDOMIndexer indexer= createIndexer(project, getIndexerId(project), props); + IndexUpdatePolicy policy= createPolicy(project); boolean rebuild= pdom.isClearedBecauseOfVersionMismatch() || - pdom.isCreatedFromScratch(); + pdom.isCreatedFromScratch() || + policy.isInitialRebuildRequested(); if (rebuild) { if (IPDOMManager.ID_NO_INDEXER.equals(indexer.getID())) { rebuild= false; @@ -537,7 +539,9 @@ public class PDOMManager implements IWritableIndexManager, IListener { Properties props= IndexerPreferences.getProperties(prj); IPDOMIndexer indexer = createIndexer(project, getIndexerId(project), props); registerIndexer(project, indexer); - createPolicy(project).clearTUs(); + final IndexUpdatePolicy policy= createPolicy(project); + policy.clearTUs(); + policy.clearInitialFlags(); IPDOMIndexerTask task= null; if (operation.wasSuccessful()) { @@ -837,6 +841,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { private void stopIndexer(IPDOMIndexer indexer) { assert !Thread.holdsLock(fProjectToPDOM); + assert !Thread.holdsLock(fUpdatePolicies); ICProject project= indexer.getProject(); synchronized (fUpdatePolicies) { IndexUpdatePolicy policy= getPolicy(project); @@ -875,12 +880,14 @@ public class PDOMManager implements IWritableIndexManager, IListener { IPDOMIndexer indexer= null; synchronized (fUpdatePolicies) { indexer= getIndexer(project); + if (indexer == null) { + createPolicy(project).requestInitialReindex(); + return Status.OK_STATUS; + } } - // don't attempt to hold lock on indexerMutex while cancelling - if (indexer != null) { - cancelIndexerJobs(indexer); - } - + // don't attempt to hold lock on indexerMutex while canceling + cancelIndexerJobs(indexer); + synchronized(fUpdatePolicies) { indexer= getIndexer(project); if (indexer != null) { @@ -1218,6 +1225,12 @@ public class PDOMManager implements IWritableIndexManager, IListener { return !IPDOMManager.ID_NO_INDEXER.equals(getIndexerId(proj)); } + public boolean isIndexerSetupPostponed(ICProject proj) { + synchronized(fSetupParticipants) { + return fPostponedProjects.contains(proj); + } + } + public void update(ICElement[] tuSelection, int options) throws CoreException { Map> projectsToElements= splitSelection(tuSelection); for (Map.Entry> entry : projectsToElements.entrySet()) { @@ -1295,7 +1308,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } - protected boolean postponeSetup(ICProject cproject) { + protected boolean postponeSetup(final ICProject cproject) { synchronized(fSetupParticipants) { for (IndexerSetupParticipant sp : fSetupParticipants) { if (sp.postponeIndexerSetup(cproject)) { @@ -1304,8 +1317,30 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } fPostponedProjects.remove(cproject); - return false; + final IndexerSetupParticipant[] participants= fSetupParticipants.toArray(new IndexerSetupParticipant[fSetupParticipants.size()]); + Job notify= new Job(Messages.PDOMManager_notifyJob_label) { + @Override + protected IStatus run(IProgressMonitor monitor) { + monitor.beginTask(Messages.PDOMManager_notifyTask_message, participants.length); + for (final IndexerSetupParticipant p : participants) { + SafeRunner.run(new ISafeRunnable(){ + public void handleException(Throwable exception) { + CCorePlugin.log(exception); + } + public void run() throws Exception { + p.onIndexerSetup(cproject); + } + }); + monitor.worked(1); + } + return Status.OK_STATUS; + } + }; + notify.setRule(NOTIFICATION_SCHEDULING_RULE); + notify.setSystem(true); + notify.schedule(); } + return false; } /**