Bug 579065 - parallel workspace save copied from jdt JavaModelManager https://bugs.eclipse.org/bugs/show_bug.cgi?id=576646#c30 Change-Id: Id33bfe7e94d5a62c967a5dad120aa007ef845b2a Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de> Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.resources/+/190808 Tested-by: Platform Bot <platform-bot@eclipse.org>
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java index 5ad0765..83ca93f 100644 --- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java +++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/SaveManager.java
@@ -27,6 +27,8 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ForkJoinPool; import java.util.zip.*; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; @@ -1732,8 +1734,27 @@ if (root.getType() == IResource.PROJECT) return; IProject[] projects = ((IWorkspaceRoot) root).getProjects(IContainer.INCLUDE_HIDDEN); - for (IProject project : projects) - visitAndSave(project); + // never use a shared ForkJoinPool.commonPool() as it may be busy with other tasks, which might deadlock: + ForkJoinPool forkJoinPool = new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism()); + IStatus[] stats; + try { + stats = forkJoinPool.submit(() -> Arrays.stream(projects).parallel().map(project -> { + try { + visitAndSave(project); + } catch (CoreException e) { + return e.getStatus(); + } + return null; + }).filter(Objects::nonNull).toArray(IStatus[]::new)).get(); + } catch (InterruptedException | ExecutionException e) { + throw new CoreException(Status.error(Messages.resources_saveProblem, e)); + } finally { + forkJoinPool.shutdown(); + } + if (stats.length > 0) { + throw new CoreException(new MultiStatus(ResourcesPlugin.PI_RESOURCES, IStatus.ERROR, stats, + Messages.resources_saveProblem, null)); + } } /**