From 6e72125c0f02a72633a4b63ebfdfd597136cf0bd Mon Sep 17 00:00:00 2001 From: modmuss Date: Tue, 13 Jun 2023 11:16:56 +0100 Subject: [PATCH] Dont allow gradle to run game/genSources tasks in parallel (#901) * Dont allow gradle to run game/genSources tasks in parallel * Fix build --- .../fabricmc/loom/task/AbstractRunTask.java | 7 +++ .../loom/task/GenerateSourcesTask.java | 6 +++ .../loom/task/RemapTaskConfiguration.java | 3 ++ .../net/fabricmc/loom/task/RunGameTask.java | 2 +- .../util/gradle/SyncTaskBuildService.java | 52 +++++++++++++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/main/java/net/fabricmc/loom/util/gradle/SyncTaskBuildService.java diff --git a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java index d5ca8e2c..c7c4879e 100644 --- a/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java +++ b/src/main/java/net/fabricmc/loom/task/AbstractRunTask.java @@ -38,18 +38,25 @@ import java.util.stream.Collectors; import org.gradle.api.Project; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.FileCollection; +import org.gradle.api.provider.Property; +import org.gradle.api.services.ServiceReference; import org.gradle.api.specs.Spec; import org.gradle.api.tasks.JavaExec; import org.jetbrains.annotations.NotNull; import net.fabricmc.loom.configuration.ide.RunConfig; import net.fabricmc.loom.util.Constants; +import net.fabricmc.loom.util.gradle.SyncTaskBuildService; public abstract class AbstractRunTask extends JavaExec { private final RunConfig config; // We control the classpath, as we use a ArgFile to pass it over the command line: https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javac.html#commandlineargfile private final ConfigurableFileCollection classpath = getProject().getObjects().fileCollection(); + // Prevent Gradle from running two run tasks in parallel + @ServiceReference(SyncTaskBuildService.NAME) + abstract Property getSyncTask(); + public AbstractRunTask(Function configProvider) { super(); setGroup(Constants.TaskGroup.FABRIC); diff --git a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java index 0ae0a945..7f28716c 100644 --- a/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java +++ b/src/main/java/net/fabricmc/loom/task/GenerateSourcesTask.java @@ -48,6 +48,7 @@ import javax.inject.Inject; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.provider.Property; +import org.gradle.api.services.ServiceReference; import org.gradle.api.tasks.InputFile; import org.gradle.api.tasks.InputFiles; import org.gradle.api.tasks.OutputFile; @@ -72,6 +73,7 @@ import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.FileSystemUtil; import net.fabricmc.loom.util.IOStringConsumer; import net.fabricmc.loom.util.Platform; +import net.fabricmc.loom.util.gradle.SyncTaskBuildService; import net.fabricmc.loom.util.gradle.ThreadedProgressLoggerConsumer; import net.fabricmc.loom.util.gradle.ThreadedSimpleProgressLogger; import net.fabricmc.loom.util.gradle.WorkerDaemonClientsManagerHelper; @@ -111,6 +113,10 @@ public abstract class GenerateSourcesTask extends AbstractLoomTask { @Inject public abstract WorkerDaemonClientsManager getWorkerDaemonClientsManager(); + // Prevent Gradle from running two gen sources tasks in parallel + @ServiceReference(SyncTaskBuildService.NAME) + abstract Property getSyncTask(); + @Inject public GenerateSourcesTask(DecompilerOptions decompilerOptions) { this.decompilerOptions = decompilerOptions; diff --git a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java index 9f741c55..cbd3630a 100644 --- a/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java +++ b/src/main/java/net/fabricmc/loom/task/RemapTaskConfiguration.java @@ -44,6 +44,7 @@ import net.fabricmc.loom.LoomGradleExtension; import net.fabricmc.loom.util.Constants; import net.fabricmc.loom.util.gradle.GradleUtils; import net.fabricmc.loom.util.gradle.SourceSetHelper; +import net.fabricmc.loom.util.gradle.SyncTaskBuildService; public abstract class RemapTaskConfiguration implements Runnable { public static final String REMAP_JAR_TASK_NAME = "remapJar"; @@ -64,6 +65,8 @@ public abstract class RemapTaskConfiguration implements Runnable { public void run() { final LoomGradleExtension extension = LoomGradleExtension.get(getProject()); + SyncTaskBuildService.register(getProject()); + if (GradleUtils.getBooleanProperty(getProject(), Constants.Properties.DONT_REMAP)) { extension.getUnmappedModCollection().from(getTasks().getByName(JavaPlugin.JAR_TASK_NAME)); return; diff --git a/src/main/java/net/fabricmc/loom/task/RunGameTask.java b/src/main/java/net/fabricmc/loom/task/RunGameTask.java index faf7cebb..05d87116 100644 --- a/src/main/java/net/fabricmc/loom/task/RunGameTask.java +++ b/src/main/java/net/fabricmc/loom/task/RunGameTask.java @@ -29,7 +29,7 @@ import javax.inject.Inject; import net.fabricmc.loom.configuration.ide.RunConfig; import net.fabricmc.loom.configuration.ide.RunConfigSettings; -public class RunGameTask extends AbstractRunTask { +public abstract class RunGameTask extends AbstractRunTask { @Inject public RunGameTask(RunConfigSettings settings) { super(proj -> RunConfig.runConfig(proj, settings)); diff --git a/src/main/java/net/fabricmc/loom/util/gradle/SyncTaskBuildService.java b/src/main/java/net/fabricmc/loom/util/gradle/SyncTaskBuildService.java new file mode 100644 index 00000000..9a5be02b --- /dev/null +++ b/src/main/java/net/fabricmc/loom/util/gradle/SyncTaskBuildService.java @@ -0,0 +1,52 @@ +/* + * This file is part of fabric-loom, licensed under the MIT License (MIT). + * + * Copyright (c) 2018-2021 FabricMC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package net.fabricmc.loom.util.gradle; + +import org.gradle.api.Project; +import org.gradle.api.services.BuildService; +import org.gradle.api.services.BuildServiceParameters; + +/** + * Add the following snippet to task to prevent tasks running asynchronously with any other task with the same build service. + * + *
{@code
+ * @ServiceReference(SyncTaskBuildService.NAME)
+ * abstract Property getSyncTask();
+ * }
+ */ +public abstract class SyncTaskBuildService implements BuildService { + public static final String NAME = "loomSyncTask"; + + public static void register(Project project) { + project.getGradle().getSharedServices().registerIfAbsent( + NAME, + SyncTaskBuildService.class, + spec -> spec.getMaxParallelUsages().set(1) + ); + } + + public interface Params extends BuildServiceParameters { + } +}