1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +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
* 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) {

View file

@ -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;
}
}