From 76ab31f44a34a3f61f649bf61a3b114f590a2954 Mon Sep 17 00:00:00 2001 From: Andrey Loskutov Date: Fri, 28 Aug 2015 17:33:48 +0200 Subject: [PATCH] Don't run ResourceRefreshJob as Workspace job to avoid resource events ResourceRefreshJob is triggered each time user activates Eclipse window, even if there are no Git configured projects in the workspace and no changes in configured Git repositories. Unfortunately even if the job detects that it has nothing to do, it *always* triggers workspace change events and autobuild job executions. ResourceRefreshJob is a subclass of InternalWorkspaceJob, so just via entering runInWorkspace() method a sequence of calls below is always executed: workspace.prepareOperation() workspace.beginOperation() workspace.endOperation() The last one always dispatches ResourceChangeEvent to all IResourceChangeListener's and so triggers also auto build job (which usually simply doesn't do anything). Although I have no example how it can cause real harm in production environment, alone debugging the build process in Eclipse is impossible because of permanent interruptions from ResourceRefreshJob. Change-Id: Idc23fd3cf4d71d36b16af2d4855770a4b70927cd Signed-off-by: Andrey Loskutov --- .../src/org/eclipse/egit/ui/Activator.java | 64 ++++++++++++++-------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java index c93d19713..09834a2bc 100644 --- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java +++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java @@ -25,8 +25,9 @@ import java.util.Set; import org.eclipse.core.net.proxy.IProxyService; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRunnable; import org.eclipse.core.resources.ResourcesPlugin; -import org.eclipse.core.resources.WorkspaceJob; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -386,7 +387,7 @@ public class Activator extends AbstractUIPlugin implements DebugOptionsListener * Refresh projects in repositories that we suspect may have resource * changes. */ - static class ResourceRefreshJob extends WorkspaceJob implements + static class ResourceRefreshJob extends Job implements IndexChangedListener { ResourceRefreshJob() { @@ -398,7 +399,7 @@ public class Activator extends AbstractUIPlugin implements DebugOptionsListener private Set repositoriesChanged = new LinkedHashSet(); @Override - public IStatus runInWorkspace(IProgressMonitor monitor) { + public IStatus run(IProgressMonitor monitor) { Set repos; synchronized (repositoriesChanged) { if (repositoriesChanged.isEmpty()) { @@ -407,9 +408,9 @@ public class Activator extends AbstractUIPlugin implements DebugOptionsListener repos = new LinkedHashSet<>(repositoriesChanged); repositoriesChanged.clear(); } - IProject[] projects = ResourcesPlugin.getWorkspace().getRoot() - .getProjects(); - Set toRefresh = new LinkedHashSet<>(); + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + IProject[] projects = workspace.getRoot().getProjects(); + final Set toRefresh = new LinkedHashSet<>(); for (IProject p : projects) { if (!p.isAccessible()) { continue; @@ -420,27 +421,42 @@ public class Activator extends AbstractUIPlugin implements DebugOptionsListener toRefresh.add(p); } } - monitor.beginTask(UIText.Activator_refreshingProjects, - toRefresh.size()); - for (IProject p : toRefresh) { - if (monitor.isCanceled()) { - return Status.CANCEL_STATUS; - } - ISchedulingRule rule = p.getWorkspace().getRuleFactory().refreshRule(p); - try { - getJobManager().beginRule(rule, monitor); - // handle missing projects after branch switch - if (p.isAccessible()) { - p.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(monitor, 1)); + if (toRefresh.isEmpty()) { + return Status.OK_STATUS; + } + + try { + workspace.run(new IWorkspaceRunnable() { + @Override + public void run(IProgressMonitor m) throws CoreException { + m.beginTask(UIText.Activator_refreshingProjects, + toRefresh.size()); + for (IProject p : toRefresh) { + if (m.isCanceled()) { + return; + } + ISchedulingRule rule = p.getWorkspace().getRuleFactory().refreshRule(p); + try { + getJobManager().beginRule(rule, m); + // handle missing projects after branch switch + if (p.isAccessible()) { + p.refreshLocal(IResource.DEPTH_INFINITE, new SubProgressMonitor(m, 1)); + } + } catch (CoreException e) { + handleError(UIText.Activator_refreshFailed, e, false); + } finally { + getJobManager().endRule(rule); + } + } } - } catch (CoreException e) { - handleError(UIText.Activator_refreshFailed, e, false); - return new Status(IStatus.ERROR, getPluginId(), e.getMessage()); - } finally { - getJobManager().endRule(rule); - } + }, workspace.getRuleFactory().refreshRule(workspace.getRoot()), + IWorkspace.AVOID_UPDATE, monitor); + } catch (CoreException e) { + handleError(UIText.Activator_refreshFailed, e, false); + return new Status(IStatus.ERROR, getPluginId(), e.getMessage()); } + if (!monitor.isCanceled()) { // re-schedule if we got some changes in the meantime synchronized (repositoriesChanged) { -- 2.11.4.GIT