1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-05 07:15:39 +02:00

Completed Indexer Job stays in Progress View, bug 264534.

This commit is contained in:
Markus Schorn 2009-02-25 09:12:10 +00:00
parent 49891dac3a
commit 6694822fcb
2 changed files with 102 additions and 80 deletions

View file

@ -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 * 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
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX Software Systems - initial API and implementation * Doug Schaefer (QNX Software Systems) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom; package org.eclipse.cdt.internal.core.pdom;
@ -23,10 +23,35 @@ import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
/** /**
* @author dschaefer * Job running multiple indexer tasks.
*
*/ */
public class PDOMIndexerJob extends Job { 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 PROGRESS_UPDATE_INTERVAL = 500;
private static final int TOTAL_MONITOR_WORK = 1000; private static final int TOTAL_MONITOR_WORK = 1000;
static volatile String sMonitorDetail= null; static volatile String sMonitorDetail= null;
@ -45,22 +70,40 @@ public class PDOMIndexerJob extends Job {
setPriority(Job.LONG); 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 @Override
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
final long start= System.currentTimeMillis();
fMonitor = monitor; fMonitor = monitor;
String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$ String taskName = CCorePlugin.getResourceString("pdom.indexer.task"); //$NON-NLS-1$
monitor.beginTask(taskName, TOTAL_MONITOR_WORK); monitor.beginTask(taskName, TOTAL_MONITOR_WORK);
Job monitorJob= startMonitorJob(monitor); ProgressUpdateJob monitorJob= new ProgressUpdateJob();
monitorJob.schedule();
try { try {
IProgressMonitor npm= new NullProgressMonitor() { IProgressMonitor npm= new NullProgressMonitor() {
@Override @Override
public boolean isCanceled() { public boolean isCanceled() {
return fMonitor.isCanceled(); synchronized(PDOMIndexerJob.this) {
return fMonitor == null || fMonitor.isCanceled();
}
} }
@Override @Override
public void setCanceled(boolean cancelled) { public void setCanceled(boolean cancelled) {
fMonitor.setCanceled(cancelled); synchronized(PDOMIndexerJob.this) {
if (fMonitor != null) {
fMonitor.setCanceled(cancelled);
}
}
} }
@Override @Override
public void subTask(String name) { public void subTask(String name) {
@ -105,16 +148,6 @@ public class PDOMIndexerJob extends Job {
} }
} }
while (currentTask != null); 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; return Status.OK_STATUS;
} }
catch (RuntimeException e) { catch (RuntimeException e) {
@ -136,7 +169,9 @@ public class PDOMIndexerJob extends Job {
throw e; throw e;
} }
finally { finally {
monitorJob.cancel(); synchronized(this) {
fMonitor= null;
}
monitor.done(); monitor.done();
} }
} }
@ -147,32 +182,15 @@ public class PDOMIndexerJob extends Job {
return name; 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) { public void cancelJobs(IPDOMIndexer indexer, boolean waitUntilCancelled) {
synchronized (taskMutex) { synchronized (taskMutex) {
if (currentTask != null && if (currentTask != null &&
(indexer == null || currentTask.getIndexer() == indexer)) { (indexer == null || currentTask.getIndexer() == indexer)) {
fMonitor.setCanceled(true); synchronized(this) {
if (fMonitor != null) {
fMonitor.setCanceled(true);
}
}
cancelledByManager = true; cancelledByManager = true;
if (waitUntilCancelled) { if (waitUntilCancelled) {
while (currentTask != null && currentTask.getIndexer() == indexer) { while (currentTask != null && currentTask.getIndexer() == indexer) {

View file

@ -97,16 +97,15 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.QualifiedName; import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.SafeRunner; import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor; 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.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.MultiRule; 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.IPreferenceChangeListener;
import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; 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; private ICProject fProject;
public PCL(ICProject prj) { public PCL(ICProject prj) {
fProject= prj; fProject= prj;
@ -137,15 +136,6 @@ public class PDOMManager implements IWritableIndexManager, IListener {
onPreferenceChange(fProject, event); 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... 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 ILanguageMappingChangeListener fLanguageChangeListener = new LanguageMappingChangeListener(this);
private final ICProjectDescriptionListener fProjectDescriptionListener; private final ICProjectDescriptionListener fProjectDescriptionListener;
private final JobChangeListener fJobChangeListener; private final JobChangeListener fJobChangeListener;
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();
@ -202,6 +193,11 @@ public class PDOMManager implements IWritableIndexManager, IListener {
public PDOMManager() { public PDOMManager() {
fProjectDescriptionListener= new CProjectDescriptionListener(this); fProjectDescriptionListener= new CProjectDescriptionListener(this);
fJobChangeListener= new JobChangeListener(this); fJobChangeListener= new JobChangeListener(this);
fPreferenceChangeListener= new IPreferenceChangeListener() {
public void preferenceChange(PreferenceChangeEvent event) {
onPreferenceChange(event);
}
};
} }
public Job startup() { public Job startup() {
@ -227,8 +223,9 @@ public class PDOMManager implements IWritableIndexManager, IListener {
// the model listener is attached outside of the job in // the model listener is attached outside of the job in
// order to avoid a race condition where its not noticed // order to avoid a race condition where its not noticed
// that new projects are being created // that new projects are being created
initializeDatabaseCache(); new InstanceScope().getNode(CCorePlugin.PLUGIN_ID).addPreferenceChangeListener(fPreferenceChangeListener);
Job.getJobManager().addJobChangeListener(fJobChangeListener); Job.getJobManager().addJobChangeListener(fJobChangeListener);
adjustCacheSize();
fIndexProviderManager.startup(); fIndexProviderManager.startup();
final CoreModel model = CoreModel.getDefault(); final CoreModel model = CoreModel.getDefault();
@ -247,8 +244,9 @@ public class PDOMManager implements IWritableIndexManager, IListener {
CCorePlugin.log(e); CCorePlugin.log(e);
} }
} }
public void shutdown() { public void shutdown() {
new InstanceScope().getNode(CCorePlugin.PLUGIN_ID).removePreferenceChangeListener(fPreferenceChangeListener);
CCorePlugin.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(fProjectDescriptionListener); CCorePlugin.getDefault().getProjectDescriptionManager().removeCProjectDescriptionListener(fProjectDescriptionListener);
final CoreModel model = CoreModel.getDefault(); final CoreModel model = CoreModel.getDefault();
model.removeElementChangedListener(fCModelListener); model.removeElementChangedListener(fCModelListener);
@ -267,25 +265,22 @@ public class PDOMManager implements IWritableIndexManager, IListener {
Job.getJobManager().removeJobChangeListener(fJobChangeListener); Job.getJobManager().removeJobChangeListener(fJobChangeListener);
} }
private void initializeDatabaseCache() { protected void onPreferenceChange(PreferenceChangeEvent event) {
adjustCacheSize(); String prop = event.getKey();
CCorePlugin.getDefault().getPluginPreferences().addPropertyChangeListener( if (prop.equals(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT)
new IPropertyChangeListener() { || prop.equals(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB)) {
public void propertyChange(PropertyChangeEvent event) { adjustCacheSize();
String prop= event.getProperty(); } else if (prop.equals(CCorePreferenceConstants.TODO_TASK_TAGS) ||
if (prop.equals(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT) || prop.equals(CCorePreferenceConstants.TODO_TASK_PRIORITIES) ||
prop.equals(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB)) { prop.equals(CCorePreferenceConstants.TODO_TASK_CASE_SENSITIVE)) {
adjustCacheSize(); reindexAll();
} }
}
}
);
} }
protected void adjustCacheSize() { protected void adjustCacheSize() {
final Preferences prefs= CCorePlugin.getDefault().getPluginPreferences(); IPreferencesService prefs = Platform.getPreferencesService();
int cachePct= prefs.getInt(CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT); int cachePct= prefs.getInt(CCorePlugin.PLUGIN_ID, CCorePreferenceConstants.INDEX_DB_CACHE_SIZE_PCT, 10, null);
int cacheMax= prefs.getInt(CCorePreferenceConstants.MAX_INDEX_DB_CACHE_SIZE_MB); 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% cachePct= Math.max(1, Math.min(50, cachePct)); // 1%-50%
cacheMax= Math.max(1, cacheMax); // >= 1mb cacheMax= Math.max(1, cacheMax); // >= 1mb
long m1= Runtime.getRuntime().maxMemory()/100L * cachePct; long m1= Runtime.getRuntime().maxMemory()/100L * cachePct;
@ -742,8 +737,6 @@ public class PDOMManager implements IWritableIndexManager, IListener {
fPrefListeners.put(prj, pcl); fPrefListeners.put(prj, pcl);
} }
IndexerPreferences.addChangeListener(prj, pcl); IndexerPreferences.addChangeListener(prj, pcl);
Preferences pref = CCorePlugin.getDefault().getPluginPreferences();
pref.addPropertyChangeListener(pcl);
} }
private void unregisterPreferenceListener(ICProject project) { private void unregisterPreferenceListener(ICProject project) {
@ -751,8 +744,6 @@ public class PDOMManager implements IWritableIndexManager, IListener {
PCL pcl= fPrefListeners.remove(prj); PCL pcl= fPrefListeners.remove(prj);
if (pcl != null) { if (pcl != null) {
IndexerPreferences.removeChangeListener(prj, pcl); 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); 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) { public void reindex(final ICProject project) {
Job job= new Job(Messages.PDOMManager_notifyJob_label) { 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); assert !Thread.holdsLock(fTaskQueue);
int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate; int sourceCount, sourceEstimate, headerCount, tickCount, tickEstimate;
@ -1085,12 +1089,12 @@ public class PDOMManager implements IWritableIndexManager, IListener {
if (detail != null) { if (detail != null) {
msg= msg+ ": " + detail; //$NON-NLS-1$ msg= msg+ ": " + detail; //$NON-NLS-1$
} }
monitor.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;
if (newTick > currentTicks) { if (newTick > currentTicks) {
monitor.worked(newTick-currentTicks); job.worked(newTick-currentTicks);
return newTick; return newTick;
} }
} }