diff --git a/patches/server/0006-JettPack-patches.patch b/patches/server/0006-JettPack-patches.patch new file mode 100644 index 0000000..df348f7 --- /dev/null +++ b/patches/server/0006-JettPack-patches.patch @@ -0,0 +1,205 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Simon Gardling +Date: Thu, 8 Jul 2021 15:03:15 -0400 +Subject: [PATCH] JettPack patches + +Use LinkedBlockingDeque in IAsyncTaskHandler + +Original license: GPLv3 +Original project: https://gitlab.com/Titaniumtown/JettPack + +Use MCUtil.asyncExecutor for MAIN_WORKER_EXECUTOR in SystemUtils + +Original code by Titaniumtown, licensed under GNU General Public License v3.0 +You can find the original code on https://gitlab.com/Titaniumtown/JettPack + +diff --git a/src/main/java/me/titaniumtown/ServerWorkerWrapper.java b/src/main/java/me/titaniumtown/ServerWorkerWrapper.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7bd88761137b2a68c04fbaa920a9ea9ce1f9e873 +--- /dev/null ++++ b/src/main/java/me/titaniumtown/ServerWorkerWrapper.java +@@ -0,0 +1,24 @@ ++package me.titaniumtown; ++ ++import com.google.common.base.Preconditions; ++import net.minecraft.Util; ++ ++public final class ServerWorkerWrapper implements Runnable { ++ private final Runnable internalRunnable; ++ ++ public ServerWorkerWrapper(Runnable runnable) { ++ this.internalRunnable = Preconditions.checkNotNull(runnable, "internalRunnable"); ++ } ++ ++ @Override ++ public final void run() { ++ try { ++ this.internalRunnable.run(); ++ return; ++ } ++ catch (Throwable throwable) { ++ Util.onThreadException(Thread.currentThread(), throwable); ++ return; ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java +index cdb7aea969b56f59d88f60bc3744e4932228c50a..b759f82b265542f42821e35ead56a5c073625d36 100644 +--- a/src/main/java/net/minecraft/Util.java ++++ b/src/main/java/net/minecraft/Util.java +@@ -73,6 +73,12 @@ import net.minecraft.util.TimeSource; + import net.minecraft.util.datafix.DataFixers; + import net.minecraft.world.level.block.state.properties.Property; + import org.slf4j.Logger; ++// JettPack start ++import java.util.concurrent.AbstractExecutorService; ++import me.titaniumtown.ServerWorkerWrapper; ++import net.minecraft.server.MCUtil; ++import java.util.Collections; ++// JettPack end + + public class Util { + static final Logger LOGGER = LogUtils.getLogger(); +@@ -165,7 +171,46 @@ public class Util { + if (i <= 0) { + executorService = MoreExecutors.newDirectExecutorService(); + } else { +- executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue(), target -> new net.minecraft.server.ServerWorkerThread(target, s, priorityModifier)); ++ //executorService = new java.util.concurrent.ThreadPoolExecutor(i, i,0L, TimeUnit.MILLISECONDS, new java.util.concurrent.LinkedBlockingQueue(), target -> new net.minecraft.server.ServerWorkerThread(target, s, priorityModifier)); // JettPack ++ // JettPack start ++ executorService = Integer.getInteger("Paper.WorkerThreadCount", i) <= 0 ? MoreExecutors.newDirectExecutorService() : new AbstractExecutorService(){ ++ private volatile boolean shutdown = false; ++ ++ @Override ++ public final List shutdownNow() { ++ this.shutdown = true; ++ return Collections.emptyList(); ++ } ++ ++ @Override ++ public final void shutdown() { ++ this.shutdown = true; ++ } ++ ++ @Override ++ public final boolean isShutdown() { ++ return this.shutdown; ++ } ++ ++ @Override ++ public final boolean isTerminated() { ++ return this.shutdown; ++ } ++ ++ @Override ++ public final boolean awaitTermination(long l2, TimeUnit timeUnit) throws InterruptedException { ++ if (!this.shutdown) { ++ throw new UnsupportedOperationException(); ++ } ++ return true; ++ } ++ ++ @Override ++ public final void execute(Runnable runnable) { ++ MCUtil.asyncExecutor.execute(new ServerWorkerWrapper(runnable)); ++ } ++ }; ++ // JettPack end + } + /* + @Override +diff --git a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +index 7a4ade1a4190bf4fbb048919ae2be230f7b80fff..5edd42d22c320e126ef377f7a9ce6fee97b2c19f 100644 +--- a/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java ++++ b/src/main/java/net/minecraft/util/thread/BlockableEventLoop.java +@@ -1,13 +1,13 @@ + package net.minecraft.util.thread; + + import com.google.common.collect.ImmutableList; +-import com.google.common.collect.Queues; ++//import com.google.common.collect.Queues; // JettPack + import com.mojang.logging.LogUtils; + import java.util.List; +-import java.util.Queue; ++//import java.util.Queue; // JettPack + import java.util.concurrent.CompletableFuture; + import java.util.concurrent.Executor; +-import java.util.concurrent.locks.LockSupport; ++//import java.util.concurrent.locks.LockSupport; // JettPack + import java.util.function.BooleanSupplier; + import java.util.function.Supplier; + import net.minecraft.util.profiling.metrics.MetricCategory; +@@ -15,12 +15,15 @@ import net.minecraft.util.profiling.metrics.MetricSampler; + import net.minecraft.util.profiling.metrics.MetricsRegistry; + import net.minecraft.util.profiling.metrics.ProfilerMeasured; + import org.slf4j.Logger; ++import java.util.concurrent.LinkedBlockingDeque; // JettPack ++import java.util.concurrent.TimeUnit; // JettPack + + public abstract class BlockableEventLoop implements ProfilerMeasured, ProcessorHandle, Executor { + private final String name; + private static final Logger LOGGER = LogUtils.getLogger(); +- private final Queue pendingRunnables = Queues.newConcurrentLinkedQueue(); ++ private final LinkedBlockingDeque pendingRunnables = new LinkedBlockingDeque(); // JettPack + private int blockingCount; ++ private R next = null; // JettPack + + protected BlockableEventLoop(String name) { + this.name = name; +@@ -89,7 +92,7 @@ public abstract class BlockableEventLoop implements Profiler + @Override + public void tell(R runnable) { + this.pendingRunnables.add(runnable); +- LockSupport.unpark(this.getRunningThread()); ++ //LockSupport.unpark(this.getRunningThread()); // JettPack + } + + @Override +@@ -117,15 +120,20 @@ public abstract class BlockableEventLoop implements Profiler + } + + public boolean pollTask() { +- R runnable = this.pendingRunnables.peek(); +- if (runnable == null) { +- return false; +- } else if (this.blockingCount == 0 && !this.shouldRun(runnable)) { ++ // JettPack start ++ if (this.next == null && !this.pendingRunnables.isEmpty()) { ++ this.waitForTasks(); ++ } ++ ++ if (this.next == null) { + return false; + } else { +- this.doRunTask(this.pendingRunnables.remove()); ++ R r2 = this.next; ++ this.next = null; ++ this.doRunTask(r2); + return true; + } ++ // JettPack end + } + + public void managedBlock(BooleanSupplier stopCondition) { +@@ -144,8 +152,18 @@ public abstract class BlockableEventLoop implements Profiler + } + + protected void waitForTasks() { +- Thread.yield(); +- LockSupport.parkNanos("waiting for tasks", 100000L); ++ // JettPack start ++ if (this.next != null) { ++ throw new IllegalStateException("next != null"); ++ } ++ try { ++ this.next = this.pendingRunnables.poll(100L, TimeUnit.MICROSECONDS); ++ return; ++ } ++ catch (InterruptedException interruptedException) { ++ return; ++ } ++ // JettPack end + } + + protected void doRunTask(R task) {