Created
April 16, 2020 08:22
-
-
Save aikar/5ec9c1dc84e8a1a1b848b409248990c3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/main/java/net/minecraft/server/CrashReport.java b/src/main/java/net/minecraft/server/CrashReport.java | |
index 3de19c998..c7dc8787c 100644 | |
--- a/src/main/java/net/minecraft/server/CrashReport.java | |
+++ b/src/main/java/net/minecraft/server/CrashReport.java | |
@@ -257,6 +257,7 @@ public class CrashReport { | |
} | |
public static CrashReport a(Throwable throwable, String s) { | |
+ if (throwable instanceof ThreadDeath) com.destroystokyo.paper.util.SneakyThrow.sneaky(throwable); // Paper | |
while (throwable instanceof CompletionException && throwable.getCause() != null) { | |
throwable = throwable.getCause(); | |
} | |
diff --git a/src/main/java/net/minecraft/server/DedicatedServer.java b/src/main/java/net/minecraft/server/DedicatedServer.java | |
index 1ef7890da..e62ca0543 100644 | |
--- a/src/main/java/net/minecraft/server/DedicatedServer.java | |
+++ b/src/main/java/net/minecraft/server/DedicatedServer.java | |
@@ -750,7 +750,7 @@ public class DedicatedServer extends MinecraftServer implements IMinecraftServer | |
@Override | |
public void stop() { | |
super.stop(); | |
- SystemUtils.f(); | |
+ //SystemUtils.f(); // Paper - moved into super | |
} | |
@Override | |
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java | |
index 36fff92f3..a386c1ab4 100644 | |
--- a/src/main/java/net/minecraft/server/MinecraftServer.java | |
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java | |
@@ -144,6 +144,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
private final ResourcePackRepository<ResourcePackLoader> resourcePackRepository; | |
@Nullable | |
private ResourcePackSourceFolder resourcePackFolder; | |
+ public volatile Thread shutdownThread; // Paper | |
public CommandDispatcher commandDispatcher; | |
private final CraftingManager craftingManager; | |
private final TagRegistry tagRegistry; | |
@@ -737,7 +738,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
// CraftBukkit start - prevent double stopping on multiple threads | |
synchronized(stopLock) { | |
if (hasStopped) return; | |
+ shutdownThread = Thread.currentThread(); | |
hasStopped = true; | |
+ org.spigotmc.WatchdogThread.doStop(); // Paper | |
+ if (!isMainThread()) { | |
+ this.getThread().stop(); | |
+ } | |
} | |
// CraftBukkit end | |
MinecraftServer.LOGGER.info("Stopping server"); | |
@@ -794,8 +800,18 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
this.getUserCache().c(false); // Paper | |
} | |
// Spigot end | |
+ // Paper start - move final shutdown items here | |
+ LOGGER.info("Flushing Chunk IO"); | |
com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper | |
- System.exit(0); // Paper | |
+ LOGGER.info("Closing Thread Pool"); | |
+ SystemUtils.shutdownServerThreadPool(); // Paper | |
+ LOGGER.info("Closing Server"); | |
+ try { | |
+ net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender | |
+ } catch (Exception e) { | |
+ } | |
+ this.exit(); | |
+ // Paper end | |
} | |
public String getServerIp() { | |
@@ -887,6 +903,7 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
// Spigot End | |
public void run() { | |
+ boolean isThreadDeath = false; // Paper | |
try { | |
if (this.init()) { | |
this.nextTick = SystemUtils.getMonotonicMillis(); | |
@@ -951,6 +968,13 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
this.a((CrashReport) null); | |
} | |
} catch (Throwable throwable) { | |
+ // Paper start | |
+ if (throwable instanceof ThreadDeath) { | |
+ MinecraftServer.LOGGER.error("Main thread terminated by WatchDog due to hard crash", throwable); | |
+ isThreadDeath = true; | |
+ return; | |
+ } | |
+ // Paper end | |
MinecraftServer.LOGGER.error("Encountered an unexpected exception", throwable); | |
// Spigot Start | |
if ( throwable.getCause() != null ) | |
@@ -982,14 +1006,14 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
} catch (Throwable throwable1) { | |
MinecraftServer.LOGGER.error("Exception stopping the server", throwable1); | |
} finally { | |
- org.spigotmc.WatchdogThread.doStop(); // Spigot | |
+ //org.spigotmc.WatchdogThread.doStop(); // Spigot // Paper - move into stop | |
// CraftBukkit start - Restore terminal to original settings | |
try { | |
- net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender | |
+ //net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Move into stop | |
} catch (Exception ignored) { | |
} | |
// CraftBukkit end | |
- this.exit(); | |
+ //this.exit(); // Paper - moved into stop | |
} | |
} | |
@@ -1040,6 +1064,12 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas | |
@Override | |
protected TickTask postToMainThread(Runnable runnable) { | |
+ // Paper start - anything that does try to post to main during watchdog crash, run on watchdog | |
+ if (this.hasStopped && Thread.currentThread().equals(shutdownThread)) { | |
+ runnable.run(); | |
+ runnable = () -> {}; | |
+ } | |
+ // Paper end | |
return new TickTask(this.ticks, runnable); | |
} | |
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java | |
index 6d6fbf2f5..0e1703c9d 100644 | |
--- a/src/main/java/net/minecraft/server/PlayerList.java | |
+++ b/src/main/java/net/minecraft/server/PlayerList.java | |
@@ -411,7 +411,7 @@ public abstract class PlayerList { | |
cserver.getPluginManager().callEvent(playerQuitEvent); | |
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); | |
- entityplayer.playerTick();// SPIGOT-924 | |
+ if (server.isMainThread()) entityplayer.playerTick();// SPIGOT-924 // Paper - don't tick during emergency shutdowns (Watchdog) | |
// CraftBukkit end | |
// Paper start - Remove from collideRule team if needed | |
diff --git a/src/main/java/net/minecraft/server/SystemUtils.java b/src/main/java/net/minecraft/server/SystemUtils.java | |
index dc6d03062..bc8b90466 100644 | |
--- a/src/main/java/net/minecraft/server/SystemUtils.java | |
+++ b/src/main/java/net/minecraft/server/SystemUtils.java | |
@@ -109,6 +109,7 @@ public class SystemUtils { | |
return SystemUtils.c; | |
} | |
+ public static void shutdownServerThreadPool() { f(); } // Paper - OBFHELPER | |
public static void f() { | |
SystemUtils.c.shutdown(); | |
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java | |
index 5fa045998..09b03afff 100644 | |
--- a/src/main/java/net/minecraft/server/World.java | |
+++ b/src/main/java/net/minecraft/server/World.java | |
@@ -786,6 +786,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { | |
gameprofilerfiller.exit(); | |
} catch (Throwable throwable) { | |
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper | |
// Paper start - Prevent tile entity and entity crashes | |
String msg = "TileEntity threw exception at " + tileentity.world.getWorld().getName() + ":" + tileentity.position.getX() + "," + tileentity.position.getY() + "," + tileentity.position.getZ(); | |
System.err.println(msg); | |
@@ -861,6 +862,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { | |
try { | |
consumer.accept(entity); | |
} catch (Throwable throwable) { | |
+ if (throwable instanceof ThreadDeath) throw throwable; // Paper | |
// Paper start - Prevent tile entity and entity crashes | |
String msg = "Entity threw exception at " + entity.world.getWorld().getName() + ":" + entity.locX() + "," + entity.locY() + "," + entity.locZ(); | |
System.err.println(msg); | |
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java | |
index 8cc0f66ce..dcc44be61 100644 | |
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java | |
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java | |
@@ -1705,7 +1705,7 @@ public final class CraftServer implements Server { | |
@Override | |
public boolean isPrimaryThread() { | |
- return Thread.currentThread().equals(console.serverThread); // Paper - Fix issues with detecting main thread properly | |
+ return Thread.currentThread().equals(console.serverThread) || Thread.currentThread().equals(net.minecraft.server.MinecraftServer.getServer().shutdownThread); // Paper - Fix issues with detecting main thread properly, the only time Watchdog will be used is during a crash shutdown which is a "try our best" scenario | |
} | |
@Override | |
diff --git a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java | |
index f255c448a..899a52520 100644 | |
--- a/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java | |
+++ b/src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java | |
@@ -30,7 +30,7 @@ public class ServerShutdownThread extends Thread { | |
// Paper end | |
} finally { | |
try { | |
- net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Use TerminalConsoleAppender | |
+ //net.minecrell.terminalconsole.TerminalConsoleAppender.close(); // Paper - Move into stop | |
} catch (Exception e) { | |
} | |
} | |
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java | |
index 6dda6d168..acc880c7c 100644 | |
--- a/src/main/java/org/spigotmc/WatchdogThread.java | |
+++ b/src/main/java/org/spigotmc/WatchdogThread.java | |
@@ -67,10 +67,10 @@ public class WatchdogThread extends Thread | |
// Paper start | |
Logger log = Bukkit.getServer().getLogger(); | |
long currentTime = monotonicMillis(); | |
- if ( lastTick != 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog") ) | |
+ MinecraftServer server = MinecraftServer.getServer(); | |
+ if ( !server.isRunning() || (lastTick != 0 && currentTime > lastTick + earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) ) | |
{ | |
- MinecraftServer server = MinecraftServer.getServer(); | |
- boolean isLongTimeout = currentTime > lastTick + timeoutTime || !server.isRunning(); | |
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime || (!server.isRunning() && !server.hasStopped() && currentTime > lastTick + 1000); | |
// Don't spam early warning dumps | |
if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue; | |
if ( !isLongTimeout && server.hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment