diff options
author | Ed Swartz | 2010-06-04 13:44:17 +0000 |
---|---|---|
committer | Ed Swartz | 2010-06-04 13:44:17 +0000 |
commit | 0a49af8c694fabeb3a5adaa3b1d10428cc8259e4 (patch) | |
tree | 84966d5ba850bc721c3301f618ad230d9585aa62 /debug | |
parent | 2314988bc200043ac72f3d0d00870f20924c541d (diff) | |
download | org.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')
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 |