diff --git a/bndtools.core/src/bndtools/central/RepositoriesViewRefresher.java b/bndtools.core/src/bndtools/central/RepositoriesViewRefresher.java index 6fa8324e3d..feaccf8dbf 100644 --- a/bndtools.core/src/bndtools/central/RepositoriesViewRefresher.java +++ b/bndtools.core/src/bndtools/central/RepositoriesViewRefresher.java @@ -52,15 +52,17 @@ enum State { private final AtomicReference state = new AtomicReference<>(State.IDLE); private final ServiceRegistration registration; private final Map viewers = new ConcurrentHashMap<>(); + private final BundleContext context; RepositoriesViewRefresher() { ServiceRegistration reg = null; Bundle bundle = FrameworkUtil.getBundle(RepositoriesViewRefresher.class); if (bundle != null) { - BundleContext context = bundle.getBundleContext(); + context = bundle.getBundleContext(); if (context != null) reg = context.registerService(RepositoryListenerPlugin.class, this, null); - } + } else + context = null; this.registration = reg; } @@ -90,8 +92,6 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { ensureLoaded(monitor, repos, ws); - // get repositories first, then do UI thread work - final Map, List> entryRepos = new HashMap<>(); for (Map.Entry entry : viewers.entrySet()) { @@ -99,28 +99,25 @@ public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { .getRepositories()); } - // - // And now back to the UI thread - // + state.set(State.BUSY); - getDisplay().asyncExec(() -> { - state.set(State.BUSY); - - for (Map.Entry entry : viewers.entrySet()) { + for (Map.Entry entry : viewers.entrySet()) { - TreePath[] expandedTreePaths = entry.getKey() - .getExpandedTreePaths(); + TreeViewer viewer = entry.getKey(); + viewer.getControl() + .getDisplay() + .asyncExec(() -> { + TreePath[] expandedTreePaths = viewer.getExpandedTreePaths(); - entry.getKey() - .setInput(entryRepos.get(entry)); + viewer.setInput(entryRepos.get(entry)); if (expandedTreePaths != null && expandedTreePaths.length > 0) - entry.getKey() - .setExpandedTreePaths(expandedTreePaths); - } - if (state.getAndSet(State.IDLE) == State.REDO) { - refreshRepositories(null); - } - }); + viewer.setExpandedTreePaths(expandedTreePaths); + }); + + } + if (state.getAndSet(State.IDLE) == State.REDO) { + refreshRepositories(null); + } return Status.OK_STATUS; } }.schedule(1000); @@ -197,13 +194,6 @@ public void close() { registration.unregister(); } - public static Display getDisplay() { - Display display = Display.getCurrent(); - if (display == null) - display = Display.getDefault(); - return display; - } - public void setRepositories(final TreeViewer viewer, final RefreshModel refresh) { if (state.updateAndGet(current -> (current == State.IDLE) ? State.BUSY : State.REDO) == State.REDO) { return; diff --git a/bndtools.core/src/bndtools/explorer/BndtoolsExplorer.java b/bndtools.core/src/bndtools/explorer/BndtoolsExplorer.java index c62f6a2a3a..00250dbc8b 100644 --- a/bndtools.core/src/bndtools/explorer/BndtoolsExplorer.java +++ b/bndtools.core/src/bndtools/explorer/BndtoolsExplorer.java @@ -247,6 +247,7 @@ public void linkActivated(HyperlinkEvent e) { @Override public void dispose() { + model.close(); closeables.forEach(IO::close); super.dispose(); } diff --git a/bndtools.core/src/bndtools/explorer/Model.java b/bndtools.core/src/bndtools/explorer/Model.java index 155ac29f6b..8318b470e6 100644 --- a/bndtools.core/src/bndtools/explorer/Model.java +++ b/bndtools.core/src/bndtools/explorer/Model.java @@ -21,13 +21,14 @@ class Model { IProject selectedProject; Object selection; String prompt; - String message = "initializing workspace"; + String message = "initializing workspace"; int severity; String filterText; final AtomicBoolean filterDirty = new AtomicBoolean(false); - final List updates = new ArrayList<>(); - final AtomicBoolean dirty = new AtomicBoolean(false); - final Set pinned = new HashSet<>(); + final List updates = new ArrayList<>(); + final AtomicBoolean dirty = new AtomicBoolean(false); + final Set pinned = new HashSet<>(); + boolean closed; void setSelectedProject(IProject project) { if (project != selectedProject) { @@ -116,7 +117,7 @@ void update() { * This runs async on the display thread. */ private void update0() { - if (dirty.getAndSet(false)) { + if (dirty.getAndSet(false) && !closed) { updates.forEach(Runnable::run); } } @@ -140,4 +141,17 @@ void setActualSelection(Object selection) { update(); } + void close() { + assert isCurrent(); + closed = true; + } + + boolean isCurrent() { + Display current = Display.getCurrent(); + if (current == null) + return false; + + return Thread.currentThread() == current.getThread(); + } + } diff --git a/bndtools.jareditor/src/bndtools/jareditor/internal/JARTreePage.java b/bndtools.jareditor/src/bndtools/jareditor/internal/JARTreePage.java index 6d15f66351..2e05a71662 100644 --- a/bndtools.jareditor/src/bndtools/jareditor/internal/JARTreePage.java +++ b/bndtools.jareditor/src/bndtools/jareditor/internal/JARTreePage.java @@ -1,6 +1,7 @@ package bndtools.jareditor.internal; import java.net.URI; +import java.util.concurrent.atomic.AtomicInteger; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; @@ -25,8 +26,9 @@ public class JARTreePage extends FormPage { private JARTreePart tree; private JARTreeEntryPart entry; private URI uri; - private boolean loading; + final AtomicInteger loading = new AtomicInteger(); private IFolder folder; + private boolean closed; public JARTreePage(JAREditor editor, String id, String title) { super(editor, id, title); @@ -83,6 +85,7 @@ public void setActive(boolean active) { @Override public void dispose() { + this.closed = true; titleImg.dispose(); setFolder(null); super.dispose(); @@ -92,11 +95,22 @@ private void update() { assert JAREditor.isDisplayThread(); - if (loading || tree == null || !isActive()) + if (tree == null || !isActive()) return; - loading = true; - JAREditor.background("Reading zip file", monitor -> getFolder(uri, monitor), folder -> { + if (loading.getAndIncrement() > 1) + return; + + JAREditor.background("Reading zip file", monitor -> { + IFolder folder; + do { + folder = getFolder(uri, monitor); + loading.getAndDecrement(); + } while (loading.getAndSet(0) > 0); + return folder; + }, folder -> { + if (closed) + return; setFolder(folder); tree.setFormInput(folder); }); @@ -111,8 +125,10 @@ void setInput(URI uri) { assert JAREditor.isDisplayThread(); + if (this.uri != null && this.uri.equals(uri)) + return; + this.uri = uri; - this.loading = false; update(); }