From 2f8f47ae3efcb9bc5b03db406afc9f7940c1661d Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Mon, 8 May 2023 09:57:53 -0400 Subject: [PATCH] Ensure the context class loader is set for the resource reload executors --- .../org/embeddedt/modernfix/ModernFix.java | 10 ++-- .../modernfix/resources/ReloadExecutor.java | 48 +++++++++++++++++++ 2 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 common/src/main/java/org/embeddedt/modernfix/resources/ReloadExecutor.java diff --git a/common/src/main/java/org/embeddedt/modernfix/ModernFix.java b/common/src/main/java/org/embeddedt/modernfix/ModernFix.java index 18f99171..cbd44bf4 100644 --- a/common/src/main/java/org/embeddedt/modernfix/ModernFix.java +++ b/common/src/main/java/org/embeddedt/modernfix/ModernFix.java @@ -9,10 +9,11 @@ import org.apache.logging.log4j.Logger; import org.embeddedt.modernfix.command.ModernFixCommands; import org.embeddedt.modernfix.core.ModernFixMixinPlugin; import org.embeddedt.modernfix.platform.ModernFixPlatformHooks; +import org.embeddedt.modernfix.resources.ReloadExecutor; import org.embeddedt.modernfix.util.ClassInfoManager; import java.lang.management.ManagementFactory; -import java.util.concurrent.*; +import java.util.concurrent.Executor; // The value here should match an entry in the META-INF/mods.toml file public class ModernFix { @@ -31,12 +32,7 @@ public class ModernFix { static { if(ModernFixMixinPlugin.instance.isOptionEnabled("perf.dedicated_reload_executor.ReloadExecutor")) { - try { - resourceReloadService = Util.makeExecutor("ResourceReload"); - } catch(Throwable e) { - LOGGER.error("Error creating resource reload service, using fallback", e); - resourceReloadService = Util.backgroundExecutor(); - } + resourceReloadService = ReloadExecutor.createCustomResourceReloadExecutor(); } else { resourceReloadService = Util.backgroundExecutor(); } diff --git a/common/src/main/java/org/embeddedt/modernfix/resources/ReloadExecutor.java b/common/src/main/java/org/embeddedt/modernfix/resources/ReloadExecutor.java new file mode 100644 index 00000000..ec35c84a --- /dev/null +++ b/common/src/main/java/org/embeddedt/modernfix/resources/ReloadExecutor.java @@ -0,0 +1,48 @@ +package org.embeddedt.modernfix.resources; + +import net.minecraft.ReportedException; +import net.minecraft.server.Bootstrap; +import org.embeddedt.modernfix.ModernFix; + +import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.atomic.AtomicInteger; + +public class ReloadExecutor { + public static ExecutorService createCustomResourceReloadExecutor() { + ClassLoader loader = ReloadExecutor.class.getClassLoader(); + AtomicInteger workerCount = new AtomicInteger(0); + return new ForkJoinPool(ForkJoinPool.getCommonPoolParallelism(), (forkJoinPool) -> { + ForkJoinWorkerThread forkJoinWorkerThread = new ForkJoinWorkerThread(forkJoinPool) { + protected void onTermination(Throwable throwOnTermination) { + if (throwOnTermination != null) { + ModernFix.LOGGER.warn("{} died", this.getName(), throwOnTermination); + } else { + ModernFix.LOGGER.debug("{} shutdown", this.getName()); + } + + super.onTermination(throwOnTermination); + } + }; + // needed to prevent weirdness on some systems + forkJoinWorkerThread.setContextClassLoader(loader); + forkJoinWorkerThread.setName("Worker-ResourceReload-" + workerCount.getAndIncrement()); + return forkJoinWorkerThread; + }, ReloadExecutor::handleException, true); + } + + private static void handleException(Thread thread, Throwable throwable) { + if (throwable instanceof CompletionException) { + throwable = throwable.getCause(); + } + + if (throwable instanceof ReportedException) { + Bootstrap.realStdoutPrintln(((ReportedException)throwable).getReport().getFriendlyReport()); + System.exit(-1); + } + + ModernFix.LOGGER.error(String.format("Caught exception in thread %s", thread), throwable); + } +}