Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Stocker2014-09-16 09:59:36 +0000
committerRobin Stocker2014-09-16 09:59:36 +0000
commit40fb5af199ce28bb6ee363c1208c7fcc033d3ada (patch)
tree9bd680c726ac9d0337df7e12cb635de83536da4a
parentf43e4b230d9a170a64b4bd7fa193f0d5e101c2ff (diff)
downloadegit-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>
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/CoreText.java3
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/internal/coretext.properties1
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/project/GitProjectData.java29
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);
+ }
+ }
+ }
}

Back to the top