diff options
author | Robin Stocker | 2014-09-16 09:59:36 +0000 |
---|---|---|
committer | Robin Stocker | 2014-09-16 09:59:36 +0000 |
commit | 40fb5af199ce28bb6ee363c1208c7fcc033d3ada (patch) | |
tree | 9bd680c726ac9d0337df7e12cb635de83536da4a | |
parent | f43e4b230d9a170a64b4bd7fa193f0d5e101c2ff (diff) | |
download | egit-40fb5af199ce28bb6ee363c1208c7fcc033d3ada.tar.gz egit-40fb5af199ce28bb6ee363c1208c7fcc033d3ada.tar.xz egit-40fb5af199ce28bb6ee363c1208c7fcc033d3ada.zip |
Fix deadlock caused by GitProjectData.logAndUnmapGoneMappedResource
Deadlock could occur as follows:
Thread 1: In GitProjectData.get/load, the class object is locked. In
case a mapped resource is gone, RepositoryProvider.unmap is called,
which waits for job run.
Thread 2: In a job run, GitProvider.getData is called, which waits to
lock the GitProjectData class.
There are also other situations, all of which are caused by
logAndUnmapGoneMappedResource calling RepositoryProvider.unmap. By doing
that in a job where the GitProjectData class is no longer locked, this
should be solved.
Bug: 425973
Change-Id: I74ecc26d696057896ac2790974e9c2e9687c783e
Signed-off-by: Robin Stocker <robin@nibor.org>
3 files changed, 28 insertions, 5 deletions
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java index 4ff0ce284b..ba0a383a56 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java @@ -373,6 +373,9 @@ public class CoreText extends NLS { public static String GitProjectData_repositoryChangedTaskName; /** */ + public static String GitProjectData_UnmapJobName; + + /** */ public static String GitProjectData_UnmappingGoneResourceFailed; /** */ diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties index af2de271a2..2039eb66ee 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties @@ -149,6 +149,7 @@ GitSubscriberMergeContext_FailedRefreshSyncView=Failed to refresh synchronize vi GitProjectData_repositoryChangedJobName=Git repository changed GitProjectData_repositoryChangedTaskName=Git repository changed +GitProjectData_UnmapJobName=Disconnecting project {0} from Git repository GitProjectData_UnmappingGoneResourceFailed=Unmapping gone mapped resource {0} failed GitResourceVariantTreeSubscriber_fetchTaskName=Fetching data from git repositories diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java index 5ad2ba451b..d62e5c5abd 100644 --- a/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java +++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java @@ -530,11 +530,8 @@ public class GitProjectData { CoreText.GitProjectData_mappedResourceGone, m.toString()), new FileNotFoundException(m.getContainerPath().toString())); m.clear(); - try { - RepositoryProvider.unmap(getProject()); - } catch (TeamException e) { - Activator.logError(CoreText.GitProjectData_UnmappingGoneResourceFailed, e); - } + UnmapJob unmapJob = new UnmapJob(getProject()); + unmapJob.schedule(); } private void protect(IResource resource) { @@ -553,4 +550,26 @@ public class GitProjectData { c = c.getParent(); } } + + private static class UnmapJob extends Job { + + private final IProject project; + + private UnmapJob(IProject project) { + super(MessageFormat.format(CoreText.GitProjectData_UnmapJobName, + project.getName())); + this.project = project; + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + RepositoryProvider.unmap(project); + return Status.OK_STATUS; + } catch (TeamException e) { + return new Status(IStatus.ERROR, Activator.getPluginId(), + CoreText.GitProjectData_UnmappingGoneResourceFailed, e); + } + } + } } |