diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java index bb637827..b8710df8 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mod/server/ArclightServer.java @@ -15,6 +15,7 @@ import net.minecraftforge.server.ServerLifecycleHooks; import org.bukkit.World; import org.bukkit.craftbukkit.v.CraftServer; import org.bukkit.craftbukkit.v.command.ColouredConsoleSender; +import org.jetbrains.annotations.NotNull; import java.io.File; import java.util.Objects; @@ -23,10 +24,23 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.locks.LockSupport; +import java.util.function.Supplier; public class ArclightServer { - private static final Executor mainThreadExecutor = ArclightServer::executeOnMainThread; + private interface ExecutorWithThread extends Executor, Supplier {} + + private static final ExecutorWithThread mainThreadExecutor = new ExecutorWithThread() { + @Override + public void execute(@NotNull Runnable command) { + executeOnMainThread(command); + } + + @Override + public Thread get() { + return getMinecraftServer().getRunningThread(); + } + }; private static final ExecutorService chatExecutor = Executors.newCachedThreadPool( new ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Chat Thread - #%d") .setThreadFactory(chatFactory()).build()); diff --git a/arclight-forge/src/main/java/io/izzel/arclight/boot/asm/AsyncCatcher.java b/arclight-forge/src/main/java/io/izzel/arclight/boot/asm/AsyncCatcher.java index 592cda0e..4f194cbc 100644 --- a/arclight-forge/src/main/java/io/izzel/arclight/boot/asm/AsyncCatcher.java +++ b/arclight-forge/src/main/java/io/izzel/arclight/boot/asm/AsyncCatcher.java @@ -38,6 +38,7 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; @@ -242,7 +243,15 @@ public class AsyncCatcher implements Implementer { case BLOCK: { CallbackInfoReturnable cir = new CallbackInfoReturnable<>(reason, true); CompletableFuture future = CompletableFuture.supplyAsync(method, executor); - cir.setReturnValue(future.get(5, TimeUnit.SECONDS)); + try { + cir.setReturnValue(future.get(5, TimeUnit.SECONDS)); + } catch (TimeoutException e) { + var thread = ((Supplier) executor).get(); + var ex = new Exception("Server thread"); + ex.setStackTrace(thread.getStackTrace()); + ArclightImplementer.LOGGER.error(MARKER, "Async catcher timeout", ex); + throw e; + } return cir; } case DISPATCH: {