diff options
author | Igor Fedorenko | 2017-07-10 22:43:25 +0000 |
---|---|---|
committer | Andrey Loskutov | 2017-07-11 08:11:21 +0000 |
commit | 01b82db06b6589232b10484f09a8b2738cb1cad3 (patch) | |
tree | 8132024e78b9dc6cb43ecc73f12cfc893f3d874f /org.eclipse.debug.ui | |
parent | ba40c99b85785a8844de6e4704546274345eb362 (diff) | |
download | eclipse.platform.debug-I20170718-2000.tar.gz eclipse.platform.debug-I20170718-2000.tar.xz eclipse.platform.debug-I20170718-2000.zip |
Bug 519433 - group model changed events processed on ui threadI20170725-2000I20170724-2000I20170723-2000I20170722-2000I20170722-0045I20170721-2000I20170720-2000I20170719-2000I20170719-0600I20170719-0040I20170718-2000I20170718-0355I20170717-2000I20170717-0350I20170716-2000I20170716-0130I20170715-2000I20170714-2000I20170713-2000
Change-Id: Ifd6e74ef734a26e52168a6317622688c301096f5
Signed-off-by: Igor Fedorenko <igor@ifedorenko.com>
Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
Diffstat (limited to 'org.eclipse.debug.ui')
-rw-r--r-- | org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java | 95 |
1 files changed, 89 insertions, 6 deletions
diff --git a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java index 24e0b712d..9afa548cf 100644 --- a/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java +++ b/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/viewers/model/TreeModelContentProvider.java @@ -53,6 +53,7 @@ import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.widgets.Display; +import org.eclipse.ui.progress.WorkbenchJob; /** * Content provider for a virtual tree. @@ -158,6 +159,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon if (fViewer == null) { return; } + fDelayedDoModelChangeJob.shutdown(); Assert.isTrue( getViewer().getDisplay().getThread() == Thread.currentThread() ); @@ -382,6 +384,92 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon } } + private static class DelayedDoModelChange { + public final IModelDelta delta; + public final IModelProxy proxy; + + public DelayedDoModelChange(final IModelDelta delta, final IModelProxy proxy) { + this.delta = delta; + this.proxy = proxy; + } + } + + private class DelayedDoModelChangedJob extends WorkbenchJob { + + // queue of submitted deltas to process + private final List<DelayedDoModelChange> fQueue = new ArrayList<>(); + private boolean shutdown; + + public DelayedDoModelChangedJob() { + super("Delayed model change job"); //$NON-NLS-1$ + setSystem(true); + setUser(false); + } + + @Override + public IStatus runInUIThread(IProgressMonitor monitor) { + List<DelayedDoModelChange> currentBatch = new ArrayList<>(); + synchronized (fQueue) { + if (shutdown || fQueue.isEmpty()) { + return Status.OK_STATUS; + } + currentBatch = new ArrayList<>(fQueue); + fQueue.clear(); + } + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) { + DebugUIPlugin.trace("Delayed batch size: " + currentBatch.size()); //$NON-NLS-1$ + } + for (Iterator<DelayedDoModelChange> iterator = currentBatch.iterator(); iterator.hasNext();) { + DelayedDoModelChange change = iterator.next(); + if (monitor.isCanceled()) { + restoreQueue(currentBatch); + return Status.CANCEL_STATUS; + } + if (!change.proxy.isDisposed()) { + doModelChanged(change.delta, change.proxy); + } + iterator.remove(); + } + return Status.OK_STATUS; + } + + private void restoreQueue(List<DelayedDoModelChange> currentBatch) { + synchronized (fQueue) { + currentBatch.addAll(fQueue); + fQueue.clear(); + fQueue.addAll(currentBatch); + } + } + + public void runDelayed(final IModelDelta delta, final IModelProxy proxy) { + synchronized (fQueue) { + if (shutdown) { + return; + } + fQueue.add(new DelayedDoModelChange(delta, proxy)); + if (DebugUIPlugin.DEBUG_CONTENT_PROVIDER) { + DebugUIPlugin.trace("Delayed queue size: " + fQueue.size()); //$NON-NLS-1$ + } + } + schedule(50); + } + + public void shutdown() { + synchronized (fQueue) { + shutdown = true; + fQueue.clear(); + } + cancel(); + } + + @Override + public boolean belongsTo(Object family) { + return family == TreeModelContentProvider.this || family == TreeModelContentProvider.class; + } + } + + private final DelayedDoModelChangedJob fDelayedDoModelChangeJob = new DelayedDoModelChangedJob(); + @Override public void modelChanged(final IModelDelta delta, final IModelProxy proxy) { Display display = null; @@ -400,12 +488,7 @@ public class TreeModelContentProvider implements ITreeModelContentProvider, ICon doModelChanged(delta, proxy); } else { - fViewer.getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - doModelChanged(delta, proxy); - } - }); + fDelayedDoModelChangeJob.runDelayed(delta, proxy); } } } |