diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java index 23e506ea9e6..48a151fa0b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMIndexerJob.java @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2005, 2008 QNX Software Systems + * Copyright (c) 2005, 2009 QNX Software Systems * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * QNX Software Systems - initial API and implementation + * Doug Schaefer (QNX Software Systems) - initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom; @@ -23,10 +23,35 @@ import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; /** - * @author dschaefer - * + * Job running multiple indexer tasks. */ public class PDOMIndexerJob extends Job { + /** + * Job updating the progress monitor of the indexer job. + */ + final class ProgressUpdateJob extends Job { + private boolean fStopped= false; + + private ProgressUpdateJob() { + super(CCorePlugin.getResourceString("PDOMIndexerJob.updateMonitorJob")); //$NON-NLS-1$ + setSystem(true); + } + + @Override + protected IStatus run(IProgressMonitor m) { + int currentTick= 0; + while(!fStopped && !m.isCanceled()) { + currentTick= pdomManager.getMonitorMessage(PDOMIndexerJob.this, currentTick, TOTAL_MONITOR_WORK); + try { + Thread.sleep(PROGRESS_UPDATE_INTERVAL); + } catch (InterruptedException e) { + return Status.CANCEL_STATUS; + } + } + return Status.OK_STATUS; + } + } + private static final int PROGRESS_UPDATE_INTERVAL = 500; private static final int TOTAL_MONITOR_WORK = 1000; static volatile String sMonitorDetail= null; @@ -45,22 +70,40 @@ public class PDOMIndexerJob extends Job { setPriority(Job.LONG); } + public synchronized void subTask(String msg) { + if (fMonitor != null) { + fMonitor.subTask(msg); + } + } + + public synchronized void worked(int i) { + if (fMonitor != null) { + fMonitor.worked(i); + } + } + @Override protected IStatus run(IProgressMonitor monitor) { - final long start= System.currentTimeMillis(); fMonitor = monitor; String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$ monitor.beginTask(taskName, TOTAL_MONITOR_WORK); - Job monitorJob= startMonitorJob(monitor); + ProgressUpdateJob monitorJob= new ProgressUpdateJob(); + monitorJob.schedule(); try { IProgressMonitor npm= new NullProgressMonitor() { @Override public boolean isCanceled() { - return fMonitor.isCanceled(); + synchronized(PDOMIndexerJob.this) { + return fMonitor == null || fMonitor.isCanceled(); + } } @Override public void setCanceled(boolean cancelled) { - fMonitor.setCanceled(cancelled); + synchronized(PDOMIndexerJob.this) { + if (fMonitor != null) { + fMonitor.setCanceled(cancelled); + } + } } @Override public void subTask(String name) { @@ -105,16 +148,6 @@ public class PDOMIndexerJob extends Job { } } while (currentTask != null); - - // work-around for https://bugs.eclipse.org/bugs/show_bug.cgi?id=197258 - long rest= 100-(System.currentTimeMillis()-start); - if (rest > 0) { - try { - Thread.sleep(rest); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } return Status.OK_STATUS; } catch (RuntimeException e) { @@ -136,7 +169,9 @@ public class PDOMIndexerJob extends Job { throw e; } finally { - monitorJob.cancel(); + synchronized(this) { + fMonitor= null; + } monitor.done(); } } @@ -147,32 +182,15 @@ public class PDOMIndexerJob extends Job { return name; } - private Job startMonitorJob(final IProgressMonitor targetMonitor) { - Job monitorJob= new Job(CCorePlugin.getResourceString("PDOMIndexerJob.updateMonitorJob")) { //$NON-NLS-1$ - @Override - protected IStatus run(IProgressMonitor m) { - int currentTick= 0; - while(!m.isCanceled() && !targetMonitor.isCanceled()) { - currentTick= pdomManager.getMonitorMessage(targetMonitor, currentTick, TOTAL_MONITOR_WORK); - try { - Thread.sleep(PROGRESS_UPDATE_INTERVAL); - } catch (InterruptedException e) { - return Status.CANCEL_STATUS; - } - } - return Status.OK_STATUS; - } - }; - monitorJob.setSystem(true); - monitorJob.schedule(); - return monitorJob; - } - public void cancelJobs(IPDOMIndexer indexer, boolean waitUntilCancelled) { synchronized (taskMutex) { if (currentTask != null && (indexer == null || currentTask.getIndexer() == indexer)) { - fMonitor.setCanceled(true); + synchronized(this) { + if (fMonitor != null) { + fMonitor.setCanceled(true); + } + } cancelledByManager = true; if (waitUntilCancelled) { while (currentTask != null && currentTask.getIndexer() == indexer) { 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 e64dd686b87..97634092182 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 @@ -97,16 +97,15 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; -import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.MultiRule; +import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; @@ -127,7 +126,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } - private final class PCL implements IPreferenceChangeListener, IPropertyChangeListener { + private final class PCL implements IPreferenceChangeListener { private ICProject fProject; public PCL(ICProject prj) { fProject= prj; @@ -137,15 +136,6 @@ public class PDOMManager implements IWritableIndexManager, IListener { onPreferenceChange(fProject, event); } } - public void propertyChange(PropertyChangeEvent event) { - String property = event.getProperty(); - if (property.equals(CCorePreferenceConstants.TODO_TASK_TAGS) || - property.equals(CCorePreferenceConstants.TODO_TASK_PRIORITIES) || - property.equals(CCorePreferenceConstants.TODO_TASK_CASE_SENSITIVE)) { - // Rebuild index if task tag preferences change. - reindex(fProject); - } - } } public static final int UPDATE_EXTERNAL_FILES_FOR_PROJECT = 0x10000; // must not collide with IIndexManager.UPDATE... @@ -184,6 +174,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { private ILanguageMappingChangeListener fLanguageChangeListener = new LanguageMappingChangeListener(this); private final ICProjectDescriptionListener fProjectDescriptionListener; private final JobChangeListener fJobChangeListener; + private final IPreferenceChangeListener fPreferenceChangeListener; private IndexFactory fIndexFactory= new IndexFactory(this); private IndexProviderManager fIndexProviderManager = new IndexProviderManager(); @@ -202,6 +193,11 @@ public class PDOMManager implements IWritableIndexManager, IListener { public PDOMManager() { fProjectDescriptionListener= new CProjectDescriptionListener(this); fJobChangeListener= new JobChangeListener(this); + fPreferenceChangeListener= new IPreferenceChangeListener() { + public void preferenceChange(PreferenceChangeEvent event) { + onPreferenceChange(event); + } + }; } public Job startup() { @@ -227,8 +223,9 @@ public class PDOMManager implements IWritableIndexManager, IListener { // the model listener is attached outside of the job in // order to avoid a race condition where its not noticed // that new projects are being created - initializeDatabaseCache(); + new InstanceScope().getNode(CCorePlugin.PLUGIN_ID).addPreferenceChangeListener(fPreferenceChangeListener); Job.getJobManager().addJobChangeListener(fJobChangeListener); + adjustCacheSize(); fIndexProviderManager.startup(); final CoreModel model = CoreModel.getDefault(); @@ -247,8 +244,9 @@ public class PDOMManager implements IWritableIndexManager, IListener { CCorePlugin.log(e); } } - + public void shutdown() { + new InstanceScope().getNode(CCorePlugin.PLUGIN_ID).removePreferenceChangeListener(fPreferenceChangeListener); CCorePlugin.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(fProjectDescriptionListener); final CoreModel model = CoreModel.getDefault(); model.removeElementChangedListener(fCModelListener); @@ -267,25 +265,22 @@ public class PDOMManager implements IWritableIndexManager, IListener { Job.getJobManager().removeJobChangeListener(fJobChangeListener); } - private void initializeDatabaseCache() { - adjustCacheSize(); - CCorePlugin.getDefault().getPluginPreferences().addPropertyChangeListener( - new IPropertyChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - String prop= event.getProperty(); - if (prop.equals(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT) || - prop.equals(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB)) { - adjustCacheSize(); - } - } - } - ); + protected void onPreferenceChange(PreferenceChangeEvent event) { + String prop = event.getKey(); + if (prop.equals(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT) + || prop.equals(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB)) { + adjustCacheSize(); + } else if (prop.equals(CCorePreferenceConstants.TODO_TASK_TAGS) || + prop.equals(CCorePreferenceConstants.TODO_TASK_PRIORITIES) || + prop.equals(CCorePreferenceConstants.TODO_TASK_CASE_SENSITIVE)) { + reindexAll(); + } } - + protected void adjustCacheSize() { - final Preferences prefs= CCorePlugin.getDefault().getPluginPreferences(); - int cachePct= prefs.getInt(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT); - int cacheMax= prefs.getInt(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB); + IPreferencesService prefs = Platform.getPreferencesService(); + int cachePct= prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT, 10, null); + int cacheMax= prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB, 64, null); cachePct= Math.max(1, Math.min(50, cachePct)); // 1%-50% cacheMax= Math.max(1, cacheMax); // >= 1mb long m1= Runtime.getRuntime().maxMemory()/100L * cachePct; @@ -742,8 +737,6 @@ public class PDOMManager implements IWritableIndexManager, IListener { fPrefListeners.put(prj, pcl); } IndexerPreferences.addChangeListener(prj, pcl); - Preferences pref = CCorePlugin.getDefault().getPluginPreferences(); - pref.addPropertyChangeListener(pcl); } private void unregisterPreferenceListener(ICProject project) { @@ -751,8 +744,6 @@ public class PDOMManager implements IWritableIndexManager, IListener { PCL pcl= fPrefListeners.remove(prj); if (pcl != null) { IndexerPreferences.removeChangeListener(prj, pcl); - Preferences pref = CCorePlugin.getDefault().getPluginPreferences(); - pref.removePropertyChangeListener(pcl); } } @@ -890,6 +881,19 @@ public class PDOMManager implements IWritableIndexManager, IListener { jobToCancel.cancelJobs(indexer, true); } } + + private void reindexAll() { + ICProject[] cProjects; + try { + cProjects = CoreModel.getDefault().getCModel().getCProjects(); + for (int i = 0; i < cProjects.length; i++) { + ICProject project = cProjects[i]; + reindex(project); + } + } catch (CModelException e) { + CCorePlugin.log(e); + } + } public void reindex(final ICProject project) { Job job= new Job(Messages.PDOMManager_notifyJob_label) { @@ -1049,7 +1053,7 @@ public class PDOMManager implements IWritableIndexManager, IListener { } } - int getMonitorMessage(IProgressMonitor monitor, int currentTicks, int base) { + int getMonitorMessage(PDOMIndexerJob job, int currentTicks, int base) { assert !Thread.holdsLock(fTaskQueue); int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate; @@ -1085,12 +1089,12 @@ public class PDOMManager implements IWritableIndexManager, IListener { if (detail != null) { msg= msg+ ": " + detail; //$NON-NLS-1$ } - monitor.subTask(msg); + job.subTask(msg); if (tickCount > 0 && tickCount <= tickEstimate) { int newTick= tickCount*base/tickEstimate; if (newTick > currentTicks) { - monitor.worked(newTick-currentTicks); + job.worked(newTick-currentTicks); return newTick; } }