Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/debug
diff options
context:
space:
mode:
authorEd Swartz2010-06-04 13:44:17 +0000
committerEd Swartz2010-06-04 13:44:17 +0000
commit0a49af8c694fabeb3a5adaa3b1d10428cc8259e4 (patch)
tree84966d5ba850bc721c3301f618ad230d9585aa62 /debug
parent2314988bc200043ac72f3d0d00870f20924c541d (diff)
downloadorg.eclipse.cdt-0a49af8c694fabeb3a5adaa3b1d10428cc8259e4.tar.gz
org.eclipse.cdt-0a49af8c694fabeb3a5adaa3b1d10428cc8259e4.tar.xz
org.eclipse.cdt-0a49af8c694fabeb3a5adaa3b1d10428cc8259e4.zip
Bug 315415 fixed performance issues of Executables view, esp. with files over networks
Diffstat (limited to 'debug')
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java29
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java2
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java199
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java95
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java102
-rw-r--r--debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties2
6 files changed, 334 insertions, 95 deletions
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java
index 473efb237a6..6b7bc77906c 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java
@@ -279,34 +279,15 @@ public class ExecutablesView extends ViewPart {
{
// update the remove action
removeAction.setEnabled(!newSelection.isEmpty());
-
+
+ // just immediately do this work: the source files content provider
+ // will do the work in the background
final Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
+
+ sourceFilesViewer.setInput(firstElement);
- Job setectExeJob = new Job(Messages.ExecutablesView_Select_Executable) {
-
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- if (firstElement instanceof Executable) {
- Executable executable = (Executable)firstElement;
- this.setName(Messages.ExecutablesView_Finding_Sources_Job_Name + executable.getName());
- executable.getSourceFiles(monitor);
- }
- // selection could be empty, so do this no matter what to update the source
- // files viewer
- UIJob selectExeUIJob = new UIJob(Messages.ExecutablesView_Select_Executable){
- @Override
- public IStatus runInUIThread(IProgressMonitor monitor) {
- sourceFilesViewer.setInput(firstElement);
- sourceFilesViewer.packColumns();
- return Status.OK_STATUS;
- }};
- selectExeUIJob.schedule();
- return Status.OK_STATUS;
- }};
- setectExeJob.schedule();
oldSelection = (IStructuredSelection) newSelection;
}
-
}
}
});
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java
index 92d165a5050..0de4f34c9e4 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java
@@ -52,6 +52,8 @@ public class Messages extends NLS {
public static String ExecutablesViewer_Size;
public static String ExecutablesViewer_Type;
public static String SourceFilesContentProvider_NoFilesFound;
+ public static String SourceFilesContentProvider_ReadingDebugSymbolInformationLabel;
+ public static String SourceFilesContentProvider_Refreshing;
public static String SourceFilesViewer_RefreshSourceFiles;
public static String SourceFilesViewer_Location;
public static String SourceFilesViewer_Modified;
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java
index fcf5c835b99..21a21952eb6 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java
@@ -11,27 +11,82 @@
package org.eclipse.cdt.debug.internal.ui.views.executables;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.eclipse.cdt.core.model.ITranslationUnit;
-import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.executables.Executable;
+import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
+import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
+import org.eclipse.cdt.debug.internal.ui.views.executables.SourceFilesViewer.TranslationUnitInfo;
import org.eclipse.cdt.ui.CElementContentProvider;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.core.runtime.jobs.JobChangeAdapter;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+
+public class SourceFilesContentProvider extends CElementContentProvider implements IExecutablesChangeListener {
-public class SourceFilesContentProvider extends CElementContentProvider {
+ static class QuickParseJob extends Job {
+ final Executable executable;
+ ITranslationUnit[] tus;
+
+ public QuickParseJob(Executable executable) {
+ super (Messages.SourceFilesContentProvider_ReadingDebugSymbolInformationLabel
+ + executable.getName());
+ this.executable = executable;
+ }
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ tus = executable.getSourceFiles(monitor);
+ return Status.OK_STATUS;
+ }
+ }
+
+ /** contains running jobs */
+ private Map<IPath, QuickParseJob> pathToJobMap = new HashMap<IPath, SourceFilesContentProvider.QuickParseJob>();
+
+ /** those executables for which we asked the question and got a result.
+ * NOTE: this contains a duplicate of into in Executable, because we can't
+ * guarantee or check whether Executable still has the info itself. */
+ private Map<IPath, ITranslationUnit[]> fetchedExecutables = new HashMap<IPath, ITranslationUnit[]>();
+ private final SourceFilesViewer viewer;
+
public SourceFilesContentProvider(SourceFilesViewer viewer) {
super(true, true);
+ this.viewer = viewer;
+ ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(this);
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.ui.CElementContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ ExecutablesManager.getExecutablesManager().removeExecutablesChangeListener(this);
+ synchronized (fetchedExecutables) {
+ fetchedExecutables.clear();
+ }
+ synchronized (pathToJobMap) {
+ pathToJobMap.clear();
+ }
+ super.dispose();
+ }
+
@Override
public boolean hasChildren(Object element) {
if (element instanceof ITranslationUnit) {
- IPath path = ((ITranslationUnit) element).getLocation();
- if (path != null && !path.toFile().exists())
+ TranslationUnitInfo info = SourceFilesViewer.fetchTranslationUnitInfo(
+ (Executable) viewer.getInput(), element);
+ if (info != null && !info.exists)
return false;
}
return super.hasChildren(element);
@@ -40,31 +95,127 @@ public class SourceFilesContentProvider extends CElementContentProvider {
public Object[] getElements(Object inputElement) {
if (inputElement instanceof Executable) {
final Executable executable = (Executable) inputElement;
- final ITranslationUnit[][] resultHolder = new ITranslationUnit[1][];
- Job quickParseJob = new Job("Reading Debug Symbol Information: " + executable.getName()) {
-
- @Override
- protected IStatus run(IProgressMonitor monitor) {
- ITranslationUnit[] sourceFiles = executable.getSourceFiles(monitor);
- resultHolder[0] = sourceFiles;
- return Status.OK_STATUS;
+ final IPath exePath = executable.getPath();
+
+ // look for a job that is currently fetching this info
+ QuickParseJob job;
+ synchronized (pathToJobMap) {
+ job = pathToJobMap.get(exePath);
+ }
+ if (job != null) {
+ // job is still running
+ return new String[] { Messages.SourceFilesContentProvider_Refreshing };
+ }
+
+ // see if we already checked
+ synchronized (fetchedExecutables) {
+ if (fetchedExecutables.containsKey(exePath)) {
+ return fetchedExecutables.get(exePath);
}
- };
+ }
- try {
- quickParseJob.schedule();
- quickParseJob.join();
- } catch (InterruptedException e) {
- CDebugCorePlugin.log(e);
+ // start a background job to look for the sources
+ job = new QuickParseJob(executable);
+ synchronized (pathToJobMap) {
+ pathToJobMap.put(exePath, job);
}
- ITranslationUnit[] sourceFiles = resultHolder[0];
- if (sourceFiles.length == 0)
- return new String[] { Messages.SourceFilesContentProvider_NoFilesFound + executable.getName() };
- else
- return sourceFiles;
+ // once the job finishes, update the viewer
+ final QuickParseJob theJob = job;
+ job.addJobChangeListener(new JobChangeAdapter() {
+ public void done(IJobChangeEvent event) {
+ if (event.getResult().isOK()) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ synchronized (pathToJobMap) {
+ pathToJobMap.values().remove(theJob);
+ }
+ synchronized (fetchedExecutables) {
+ fetchedExecutables.put(exePath, theJob.tus);
+ }
+ // update the viewer
+ if (!viewer.getControl().isDisposed()) {
+ viewer.getTree().setLayoutDeferred(true);
+ viewer.refresh(executable);
+ viewer.packColumns();
+ viewer.getTree().setLayoutDeferred(false);
+ }
+ }
+ });
+ }
+ }
+ });
+
+ job.schedule();
+
+ // while it's running...
+ return new String[] { Messages.SourceFilesContentProvider_Refreshing };
}
return new Object[] {};
}
-} \ No newline at end of file
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesListChanged()
+ */
+ public void executablesListChanged() {
+ // Don't clear executables -- closing/opening project doesn't imply
+ // the info is different. But cancel all the jobs in case projects
+ // were closed. It's non-obvious how to map executables to projects,
+ // so just bail and cancel all the current parsing. The viewer
+ // will be refreshed and re-request source lists for any executables
+ // that are still applicable.
+ cancelQuickParseJobs();
+ }
+
+
+ /**
+ *
+ */
+ private void cancelQuickParseJobs() {
+ synchronized (pathToJobMap) {
+ for (QuickParseJob job : pathToJobMap.values()) {
+ job.cancel();
+ }
+ pathToJobMap.clear();
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(java.util.List)
+ */
+ public void executablesChanged(List<Executable> executables) {
+ for (Executable executable : executables) {
+ IPath exePath = executable.getPath();
+ synchronized (fetchedExecutables) {
+ fetchedExecutables.remove(exePath);
+ }
+ synchronized (pathToJobMap) {
+ QuickParseJob job = pathToJobMap.get(exePath);
+ if (job != null) {
+ job.cancel();
+ pathToJobMap.remove(exePath);
+ }
+ }
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.ui.CElementContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+ */
+ @Override
+ public void inputChanged(Viewer viewer, Object oldInput, final Object newInput) {
+ super.inputChanged(viewer, oldInput, newInput);
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ // pack because the quick parse job won't run
+ if (newInput instanceof Executable
+ && fetchedExecutables.containsKey(((Executable) newInput).getPath()))
+ SourceFilesContentProvider.this.viewer.packColumns();
+ }
+ });
+ }
+}
+
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java
index 0445f22dfdd..b571f5b614e 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java
@@ -12,23 +12,27 @@
package org.eclipse.cdt.debug.internal.ui.views.executables;
import com.ibm.icu.text.DateFormat;
+
import java.util.Date;
+import java.util.List;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.debug.core.executables.Executable;
+import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
+import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
import org.eclipse.cdt.ui.CElementLabelProvider;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.DisposeEvent;
+import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Display;
-public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
+public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider implements IExecutablesChangeListener {
private SourceFilesViewer viewer;
@@ -37,28 +41,42 @@ public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
public SourceFilesLabelProvider(SourceFilesViewer viewer) {
super(new CElementLabelProvider());
this.viewer = viewer;
+
+ // brute-force clear the cache when executables change
+ ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(this);
+ viewer.getControl().addDisposeListener(new DisposeListener() {
+ public void widgetDisposed(DisposeEvent e) {
+ ExecutablesManager.getExecutablesManager().removeExecutablesChangeListener(SourceFilesLabelProvider.this);
+ }
+ });
}
@Override
public void update(ViewerCell cell) {
super.update(cell);
+ SourceFilesViewer.TranslationUnitInfo tuInfo = null;
+ Object element = cell.getElement();
+ if (element instanceof ITranslationUnit) {
+ tuInfo = SourceFilesViewer.fetchTranslationUnitInfo((Executable) viewer.getInput(), element);
+ }
+
int orgColumnIndex = cell.getColumnIndex();
if (orgColumnIndex == 0) {
- if (cell.getElement() instanceof String) {
- cell.setText((String) cell.getElement());
- Font boldFont = resourceManager.createFont(FontDescriptor.createFrom(viewer.getTree().getFont()).setStyle(SWT.BOLD));
- cell.setFont(boldFont);
+ if (element instanceof String) {
+ cell.setText((String) element);
+ Font italicFont = resourceManager.createFont(FontDescriptor.createFrom(viewer.getTree().getFont()).setStyle(SWT.ITALIC));
+ cell.setFont(italicFont);
+ } else {
+ cell.setFont(viewer.getTree().getFont());
}
} else if (orgColumnIndex == 1) {
cell.setText(null);
- if (cell.getElement() instanceof ITranslationUnit) {
- ITranslationUnit tu = (ITranslationUnit) cell.getElement();
- IPath path = tu.getLocation();
- if (path != null) {
- cell.setText(path.toOSString());
- if (path.toFile().exists())
+ if (tuInfo != null) {
+ if (tuInfo.location != null) {
+ cell.setText(tuInfo.location.toOSString());
+ if (tuInfo.exists)
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
else
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
@@ -67,11 +85,9 @@ public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
cell.setImage(null);
} else if (orgColumnIndex == 2) {
cell.setText(null);
- if (cell.getElement() instanceof ITranslationUnit) {
- Executable executable = (Executable) viewer.getInput();
- Path path = new Path(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
- cell.setText(path.toOSString());
- if (path.toFile().exists())
+ if (tuInfo != null && tuInfo.originalLocation != null) {
+ cell.setText(tuInfo.originalLocation.toOSString());
+ if (tuInfo.originalExists)
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
else
cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
@@ -79,34 +95,27 @@ public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
cell.setImage(null);
} else if (orgColumnIndex == 3) {
cell.setText(null);
- if (cell.getElement() instanceof ITranslationUnit) {
- ITranslationUnit tu = (ITranslationUnit) cell.getElement();
- IPath path = tu.getLocation();
- if (path != null && path.toFile().exists()) {
- long fileLength = path.toFile().length();
- cell.setText(Long.toString(fileLength));
+ if (tuInfo != null) {
+ if (tuInfo.exists) {
+ cell.setText(Long.toString(tuInfo.fileLength));
}
}
cell.setImage(null);
} else if (orgColumnIndex == 4) {
cell.setText(null);
- if (cell.getElement() instanceof ITranslationUnit) {
- ITranslationUnit tu = (ITranslationUnit) cell.getElement();
- IPath path = tu.getLocation();
- if (path != null && path.toFile().exists()) {
- long modified = path.toFile().lastModified();
- String dateTimeString = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date(modified));
+ if (tuInfo != null) {
+ if (tuInfo.exists) {
+ String dateTimeString = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(
+ new Date(tuInfo.lastModified));
cell.setText(dateTimeString);
}
}
cell.setImage(null);
} else if (orgColumnIndex == 5) {
cell.setText(null);
- if (cell.getElement() instanceof ITranslationUnit) {
- ITranslationUnit tu = (ITranslationUnit) cell.getElement();
- IPath path = tu.getLocation();
- if (path != null) {
- String fileExtension = path.getFileExtension();
+ if (tuInfo != null) {
+ if (tuInfo.location != null) {
+ String fileExtension = tuInfo.location.getFileExtension();
if (fileExtension != null)
cell.setText(fileExtension.toLowerCase());
}
@@ -115,4 +124,20 @@ public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
}
}
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesListChanged()
+ */
+ public void executablesListChanged() {
+ SourceFilesViewer.flushTranslationUnitCache();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(java.util.List)
+ */
+ public void executablesChanged(List<Executable> executables) {
+ // no mapping of executable -> TU maintained; just kill all for now
+ SourceFilesViewer.flushTranslationUnitCache();
+ }
+
}
+ \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java
index 340714e01c1..f69c3f7c840 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.cdt.debug.internal.ui.views.executables;
+import java.io.File;
+
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ISourceReference;
import org.eclipse.cdt.core.model.ITranslationUnit;
@@ -17,13 +19,12 @@ import org.eclipse.cdt.debug.core.CDebugCorePlugin;
import org.eclipse.cdt.debug.core.executables.Executable;
import org.eclipse.cdt.debug.internal.ui.sourcelookup.CSourceNotFoundEditorInput;
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
+import org.eclipse.cdt.internal.core.util.LRUCache;
import org.eclipse.cdt.internal.ui.util.EditorUtility;
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.IStatus;
-import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationListener;
@@ -38,12 +39,12 @@ import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
-import org.eclipse.ui.progress.UIJob;
/**
* Displays the list of source files for the executable selected in the
@@ -51,6 +52,24 @@ import org.eclipse.ui.progress.UIJob;
*/
public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant, ILaunchConfigurationListener {
+ /** Information from an ITranslationUnit for the various displayed columns */
+ static class TranslationUnitInfo {
+ /** when do we next check these attributes? time in ms */
+ long nextCheckTimestamp;
+ /** the source file location */
+ IPath location;
+ /** does the file exist? */
+ boolean exists;
+ /** length of actual file in bytes */
+ long fileLength;
+ /** {@link File#lastModified()} time for source file */
+ long lastModified;
+ /** the original source file location, e.g. from debug info */
+ IPath originalLocation;
+ /** does the original file exist? */
+ boolean originalExists;
+ }
+
private static final String P_COLUMN_ORDER_KEY_SF = "columnOrderKeySF"; //$NON-NLS-1$
private static final String P_SORTED_COLUMN_INDEX_KEY_SF = "sortedColumnIndexKeySF"; //$NON-NLS-1$
private static final String P_COLUMN_SORT_DIRECTION_KEY_SF = "columnSortDirectionKeySF"; //$NON-NLS-1$
@@ -59,6 +78,10 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic
TreeColumn originalLocationColumn;
private Tree sourceFilesTree;
+ /** Tradeoff expensiveness of checking filesystem against likelihood
+ * that files will be added/removed/changed in the given time period */
+ static final long FILE_CHECK_DELTA = 30 * 1000;
+ private static LRUCache<Object, TranslationUnitInfo> translationUnitInfoCache = new LRUCache<Object, TranslationUnitInfo>(1024);
public SourceFilesViewer(ExecutablesView view, Composite parent, int style) {
super(view, parent, style);
@@ -90,6 +113,8 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic
sourceFilesTree.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
+ DebugPlugin.getDefault().getLaunchManager().removeLaunchConfigurationListener(SourceFilesViewer.this);
+
CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().removeParticipants(
new ISourceLookupParticipant[] { SourceFilesViewer.this });
}
@@ -213,19 +238,19 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic
}
private void refreshContent() {
- UIJob refreshJob = new UIJob(Messages.SourceFilesViewer_RefreshSourceFiles) {
-
- @Override
- public IStatus runInUIThread(IProgressMonitor monitor) {
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
Object input = getInput();
if (input != null && input instanceof Executable) {
((Executable)input).setRemapSourceFiles(true);
+
+ // TODO: be more selective; we don't know what TUs go with which executables yet
+ flushTranslationUnitCache();
+
refresh(true);
}
- return Status.OK_STATUS;
}
- };
- refreshJob.schedule();
+ });
}
@Override
@@ -280,5 +305,58 @@ public class SourceFilesViewer extends BaseViewer implements ISourceLookupPartic
refreshContent();
}
}
-
+
+
+ static TranslationUnitInfo fetchTranslationUnitInfo(Executable executable, Object element) {
+ if (!(element instanceof ITranslationUnit)) {
+ return null;
+ }
+
+ ITranslationUnit tu = (ITranslationUnit) element;
+ long now = System.currentTimeMillis();
+ TranslationUnitInfo info;
+
+ synchronized (translationUnitInfoCache) {
+ info = (TranslationUnitInfo) translationUnitInfoCache.get(element);
+ }
+ if (info == null || info.nextCheckTimestamp <= now) {
+ if (info == null)
+ info = new TranslationUnitInfo();
+
+ info.location = tu.getLocation();
+ if (info.location != null) {
+ File file = info.location.toFile();
+ info.exists = file.exists();
+ info.fileLength = file.length();
+ info.lastModified = file.lastModified();
+
+ info.originalLocation = new Path(executable.getOriginalLocation(tu));
+ info.originalExists = info.originalLocation.toFile().exists();
+ } else {
+ info.exists = false;
+ info.fileLength = 0;
+ info.lastModified = 0;
+ info.originalExists = false;
+ info.originalLocation = null;
+ }
+
+ info.nextCheckTimestamp = System.currentTimeMillis() + FILE_CHECK_DELTA;
+
+ synchronized (translationUnitInfoCache) {
+ translationUnitInfoCache.put(element, info);
+ }
+ }
+ return info;
+ }
+
+ /**
+ *
+ */
+ static void flushTranslationUnitCache() {
+ synchronized (translationUnitInfoCache) {
+ translationUnitInfoCache.flush();
+ }
+
+ }
+
} \ No newline at end of file
diff --git a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties
index d83fc115585..4262cb72bcd 100644
--- a/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties
+++ b/debug/org.eclipse.cdt.debug.ui/src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties
@@ -46,6 +46,8 @@ ExecutablesViewer_RefreshExecutablesView=Refresh Executables View
ExecutablesViewer_Size=Size
ExecutablesViewer_Type=Type
SourceFilesContentProvider_NoFilesFound=No source files found in
+SourceFilesContentProvider_ReadingDebugSymbolInformationLabel=Reading Debug Symbol Information:
+SourceFilesContentProvider_Refreshing=Refreshing...
SourceFilesViewer_RefreshSourceFiles=Refresh Source Files
SourceFilesViewer_Location=Location
SourceFilesViewer_Modified=Modified

Back to the top