| author | Lieven Lemiengre | 2012-07-25 05:41:22 (EDT) |
|---|---|---|
| committer | Sven Efftinge | 2012-08-07 04:11:47 (EDT) |
| commit | b6757f357673bf395435dd998c301e8a012ab967 (patch) (side-by-side diff) | |
| tree | 2e57debf499218c212ecdc55266c55a34f0f156a | |
| parent | 2d098d3decae6e57ac7f479b62a2bfbcfd54ae14 (diff) | |
| download | org.eclipse.xtext-b6757f357673bf395435dd998c301e8a012ab967.zip org.eclipse.xtext-b6757f357673bf395435dd998c301e8a012ab967.tar.gz org.eclipse.xtext-b6757f357673bf395435dd998c301e8a012ab967.tar.bz2 | |
fixed deadlock issue with ParallelResourceLoader.java
| -rw-r--r-- | plugins/org.eclipse.xtext.builder/src/org/eclipse/xtext/builder/resourceloader/ParallelResourceLoader.java | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/plugins/org.eclipse.xtext.builder/src/org/eclipse/xtext/builder/resourceloader/ParallelResourceLoader.java b/plugins/org.eclipse.xtext.builder/src/org/eclipse/xtext/builder/resourceloader/ParallelResourceLoader.java index 74c081d..1aa625a 100644 --- a/plugins/org.eclipse.xtext.builder/src/org/eclipse/xtext/builder/resourceloader/ParallelResourceLoader.java +++ b/plugins/org.eclipse.xtext.builder/src/org/eclipse/xtext/builder/resourceloader/ParallelResourceLoader.java @@ -20,7 +20,15 @@ import java.util.concurrent.Executors; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.resource.Resource; @@ -64,6 +72,26 @@ public class ParallelResourceLoader extends AbstractResourceLoader { public LoadOperation create(ResourceSet parent, IProject project) { return new CheckedLoadOperation(new ParallelLoadOperation(parent, project)); } + + @Override + protected Resource loadResource(URI uri, ResourceSet localResourceSet, ResourceSet parentResourceSet) { + if(localResourceSet != null) { + IWorkspace workspace = ResourcesPlugin.getWorkspace(); + if(workspace != null) { + IWorkspaceRoot root = workspace.getRoot(); + if(root != null) { + IFile file = root.getFile(new Path(uri.toPlatformString(true))); + if(!file.isSynchronized(IResource.DEPTH_ZERO)) { + // don't bother trying to refresh it, this loading-thread doesn't own the project resource lock + // we will recover & load the resource in the main builder thread (that owns the project resource lock) + // (if we do try to load resources that are out of sync, we create a deadlock) + return null; + } + } + } + } + return super.loadResource(uri, localResourceSet, parentResourceSet); + } private class ParallelLoadOperation implements LoadOperation { @@ -146,6 +174,13 @@ public class ParallelResourceLoader extends AbstractResourceLoader { throw new LoadOperationException(uri, throwable.getCause()); throw new LoadOperationException(uri, throwable); } + + if(resource == null && uri != null) { + // failed to load resource in parallel (due to file synchronization issues) + // load the resource here, in the main builder thread + resource = parent.getResource(uri, true); + } + return new LoadResult(resource, uri); } @@ -154,6 +189,8 @@ public class ParallelResourceLoader extends AbstractResourceLoader { } public void load(Collection<URI> uris) { + synchronizeResources(uris); + toProcess += uris.size(); Collection<URI> workload = getSorter().sort(uris); for(URI uri : workload) { @@ -161,6 +198,24 @@ public class ParallelResourceLoader extends AbstractResourceLoader { } executor.shutdown(); } + + /** + * Make sure that all files that are about to be loaded are synchronized with the file system + */ + private void synchronizeResources(Collection<URI> toLoad) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + for(URI uri : toLoad) { + Path path = new Path(uri.toPlatformString(true)); + IFile file = root.getFile(path); + try { + if(!file.isSynchronized(IResource.DEPTH_ZERO)) { + file.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()); + } + } catch (CoreException e) { + throw new RuntimeException(e); + } + } + } public Collection<URI> cancel() { toProcess = 0; |

