Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrey Loskutov2017-11-27 10:41:40 +0000
committerAndrey Loskutov2017-11-28 17:03:59 +0000
commit13eb6669806171ab554d7a112e84deacfa14d6e9 (patch)
treede960760584e8a3bf0475ee724e89578bed65ae1
parentdf6c3d69559e319a6111d313663744107139341b (diff)
downloadeclipse.jdt.core-13eb6669806171ab554d7a112e84deacfa14d6e9.tar.gz
eclipse.jdt.core-13eb6669806171ab554d7a112e84deacfa14d6e9.tar.xz
eclipse.jdt.core-13eb6669806171ab554d7a112e84deacfa14d6e9.zip
Bug 526180 - ExternalFoldersManager.createLinkFolder is not
'synchronized' Make sure addFolder() is never working with same counter value in multiple threads and never creates multiple folders for same path. Also make sure createLinkFolder() do not complain if another thread created the folder already. Change-Id: I17929389124de083b11dbc022766e165204442b0 Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java43
1 files changed, 31 insertions, 12 deletions
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
index 902b878711..fb0087e33d 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ExternalFoldersManager.java
@@ -26,6 +26,7 @@ import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
+import java.util.concurrent.atomic.AtomicInteger;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
@@ -53,7 +54,7 @@ public class ExternalFoldersManager {
private static final String LINKED_FOLDER_NAME = ".link"; //$NON-NLS-1$
private Map folders;
private Set pendingFolders; // subset of keys of 'folders', for which linked folders haven't been created yet.
- private int counter = 0;
+ private final AtomicInteger counter = new AtomicInteger(0);
/* Singleton instance */
private static ExternalFoldersManager MANAGER;
@@ -134,22 +135,32 @@ public class ExternalFoldersManager {
private IFolder addFolder(IPath externalFolderPath, IProject externalFoldersProject, boolean scheduleForCreation) {
Map knownFolders = getFolders();
- Object existing = knownFolders.get(externalFolderPath);
- if (existing != null) {
- return (IFolder) existing;
+
+ Object existing;
+ synchronized (this) {
+ existing = knownFolders.get(externalFolderPath);
+ if (existing != null) {
+ return (IFolder) existing;
+ }
}
+
IFolder result;
do {
- result = externalFoldersProject.getFolder(LINKED_FOLDER_NAME + this.counter++);
+ result = externalFoldersProject.getFolder(LINKED_FOLDER_NAME + this.counter.incrementAndGet());
} while (result.exists());
- if (scheduleForCreation) {
- synchronized(this) {
+
+ synchronized (this) {
+ if (scheduleForCreation) {
if (this.pendingFolders == null)
this.pendingFolders = Collections.synchronizedSet(new HashSet());
+ this.pendingFolders.add(externalFolderPath);
}
- this.pendingFolders.add(externalFolderPath);
+ existing = knownFolders.get(externalFolderPath);
+ if (existing != null) {
+ return (IFolder) existing;
+ }
+ knownFolders.put(externalFolderPath, result);
}
- knownFolders.put(externalFolderPath, result);
return result;
}
@@ -173,10 +184,18 @@ public class ExternalFoldersManager {
IProject externalFoldersProject, IProgressMonitor monitor) throws CoreException {
IFolder result = addFolder(externalFolderPath, externalFoldersProject, false);
- if (!result.exists())
- result.createLink(externalFolderPath, IResource.ALLOW_MISSING_LOCAL, monitor);
- else if (refreshIfExistAlready)
+ if (!result.exists()) {
+ try {
+ result.createLink(externalFolderPath, IResource.ALLOW_MISSING_LOCAL, monitor);
+ } catch (CoreException e) {
+ // If we managed to create the folder in the meantime, don't complain
+ if (!result.exists()) {
+ throw e;
+ }
+ }
+ } else if (refreshIfExistAlready) {
result.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+ }
return result;
}

Back to the top