diff options
| author | Andrey Loskutov | 2017-11-27 10:41:40 +0000 |
|---|---|---|
| committer | Andrey Loskutov | 2017-11-28 17:03:59 +0000 |
| commit | 13eb6669806171ab554d7a112e84deacfa14d6e9 (patch) | |
| tree | de960760584e8a3bf0475ee724e89578bed65ae1 | |
| parent | df6c3d69559e319a6111d313663744107139341b (diff) | |
| download | eclipse.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.java | 43 |
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; } |
