Revert "Removed safety shutdown hook again"

Found a fix.
This reverts commit f880122add.
This commit is contained in:
JeremyStar™ 2024-08-21 01:50:49 +02:00
parent f880122add
commit 8ea4594e6f
Signed by: JeremyStarTM
GPG key ID: E366BAEF67E4704D
3 changed files with 83 additions and 0 deletions

View file

@ -32,6 +32,7 @@ import de.staropensource.sosengine.base.exceptions.dependency.UnmetDependenciesE
import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent; import de.staropensource.sosengine.base.internal.events.InternalEngineShutdownEvent;
import de.staropensource.sosengine.base.internal.types.DependencySubsystemVector; import de.staropensource.sosengine.base.internal.types.DependencySubsystemVector;
import de.staropensource.sosengine.base.logging.CrashHandler; import de.staropensource.sosengine.base.logging.CrashHandler;
import de.staropensource.sosengine.base.logging.InitLogger;
import de.staropensource.sosengine.base.logging.Logger; import de.staropensource.sosengine.base.logging.Logger;
import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.DependencyVector; import de.staropensource.sosengine.base.types.DependencyVector;
@ -40,6 +41,7 @@ import de.staropensource.sosengine.base.types.immutable.ImmutableLinkedList;
import de.staropensource.sosengine.base.utility.DependencyResolver; import de.staropensource.sosengine.base.utility.DependencyResolver;
import de.staropensource.sosengine.base.utility.Miscellaneous; import de.staropensource.sosengine.base.utility.Miscellaneous;
import de.staropensource.sosengine.base.utility.PlaceholderEngine; import de.staropensource.sosengine.base.utility.PlaceholderEngine;
import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -150,6 +152,41 @@ public final class Engine extends SubsystemClass {
@Setter @Setter
private @NotNull ShutdownHandler shutdownHandler = new Engine.JvmShutdownHandler(); private @NotNull ShutdownHandler shutdownHandler = new Engine.JvmShutdownHandler();
/**
* Contains the JVM shutdown hook thread,
* which ensures that the engine is fully shut
* down before the JVM exits.
*
* @see EngineInternals#installSafetyShutdownHook(boolean)
* @since v1-alpha4
*/
@Getter(AccessLevel.MODULE)
private final @NotNull Thread safetyShutdownHook = Thread.ofPlatform()
.name("Engine shutdown thread")
.group(getThreadGroup())
.unstarted(() -> {
// To avoid race condition or something
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {}
// Check if already shutting down
switch (state) {
case UNKNOWN, SHUTDOWN, CRASHED -> {
return;
}
}
// Print warning about shutdown
logger.warn("Trying to shut down engine using shutdown hook.\nThis approach to shutting down the engine and JVM is NOT RECOMMENDED, please use Engine#shutdown() instead.");
// Shutdown
Engine.getInstance().shutdown();
// Print last message
InitLogger.warn(getClass(), "ENGINE", EngineInformation.getVersioningCodename(), "Engine successfully shut down using shutdown hook. PLEASE USE Engine#shutdown() INSTEAD OF System#exit() or Runtime#exit()!");
});
/** /**
* Initializes the StarOpenSource Engine. * Initializes the StarOpenSource Engine.
* *
@ -172,6 +209,7 @@ public final class Engine extends SubsystemClass {
initializeClasses(); // Initialize classes initializeClasses(); // Initialize classes
if (checkEnvironment()) // Check environment if (checkEnvironment()) // Check environment
throw new IllegalStateException("Running in an incompatible environment"); throw new IllegalStateException("Running in an incompatible environment");
ensureEnvironment(); // Prepare the environment and ensure safety
populateCrashContent(); // Populate crash content populateCrashContent(); // Populate crash content
cacheEvents(); // Cache event listeners cacheEvents(); // Cache event listeners
startThreads(); // Start threads startThreads(); // Start threads
@ -224,6 +262,15 @@ public final class Engine extends SubsystemClass {
return false; return false;
} }
/**
* Ensures the execution safety of the environment.
*
* @since v1-alpha4
*/
private void ensureEnvironment() {
EngineInternals.getInstance().installSafetyShutdownHook(true);
}
/** /**
* This method populates {@link CrashHandler#crashContent} with content. * This method populates {@link CrashHandler#crashContent} with content.
* *
@ -432,6 +479,11 @@ public final class Engine extends SubsystemClass {
// Flush log messages // Flush log messages
Logger.flushLogMessages(); Logger.flushLogMessages();
// Disable safety shutdown hook
try {
Runtime.getRuntime().removeShutdownHook(safetyShutdownHook);
} catch (Exception ignored) {}
// Send events // Send events
logger.verb("Notifiying classes about shutdown"); logger.verb("Notifiying classes about shutdown");
new EngineShutdownEvent().callEvent(); new EngineShutdownEvent().callEvent();

View file

@ -19,6 +19,7 @@
package de.staropensource.sosengine.base; package de.staropensource.sosengine.base;
import de.staropensource.sosengine.base.exceptions.NoAccessException;
import de.staropensource.sosengine.base.logging.LoggerInstance; import de.staropensource.sosengine.base.logging.LoggerInstance;
import de.staropensource.sosengine.base.types.InternalAccessArea; import de.staropensource.sosengine.base.types.InternalAccessArea;
import lombok.Getter; import lombok.Getter;
@ -91,4 +92,26 @@ public final class EngineInternals {
restrictedAreas.add(area); restrictedAreas.add(area);
} }
/**
* Installs or uninstalls the JVM shutdown
* hook, which prevents the JVM from exiting
* before the engine has fully shut down.
* Highly recommended to keep enabled.
*
* @param status {@code true} to install, {@code false} otherwise
* @throws NoAccessException when restricted
* @since v1-alpha4
*/
public void installSafetyShutdownHook(boolean status) throws NoAccessException {
if (restrictedAreas.contains(InternalAccessArea.SAFETY_SHUTDOWN_HOOK))
throw new NoAccessException("The internal access area SAFETY_SHUTDOWN_HOOK has been restricted");
try {
if (status)
Runtime.getRuntime().addShutdownHook(Engine.getInstance().getSafetyShutdownHook());
else
Runtime.getRuntime().removeShutdownHook(Engine.getInstance().getSafetyShutdownHook());
} catch (IllegalArgumentException | IllegalStateException ignored) {}
}
} }

View file

@ -35,4 +35,12 @@ public enum InternalAccessArea {
* @since v1-alpha4 * @since v1-alpha4
*/ */
ALL, ALL,
/**
* Refers to the toggling of the JVM shutdown hook, which
* prevents JVM shutdowns without the engine first shutting down.
*
* @since v1-alpha4
*/
SAFETY_SHUTDOWN_HOOK,
} }