-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
144 additions
and
18 deletions.
There are no files selected for viewing
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
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
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
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
79 changes: 79 additions & 0 deletions
79
common/src/main/java/com/fox2code/foxloader/utils/WatchdogThread.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.fox2code.foxloader.utils; | ||
|
||
import java.lang.ref.WeakReference; | ||
import java.util.Map; | ||
import java.util.concurrent.CopyOnWriteArrayList; | ||
|
||
final class WatchdogThread extends Thread { | ||
private static final long T1_SECONDS = 1000L; | ||
private static final long T1_9_SECONDS = 1900L; | ||
private static WatchdogThread watchdogThread; | ||
private final CopyOnWriteArrayList<WeakReference<WatchdogTimer>> watchdogTimers; | ||
private long lastStackDump; | ||
|
||
private WatchdogThread() { | ||
this.setDaemon(true); | ||
this.setPriority(Thread.MIN_PRIORITY); | ||
this.setName("FoxLoader - Watchdog Thread"); | ||
this.watchdogTimers = new CopyOnWriteArrayList<>(); | ||
this.lastStackDump = System.currentTimeMillis(); | ||
Runtime.getRuntime().addShutdownHook(new Thread( | ||
this::interrupt, "FoxLoader - Watchdog Shutdown Thread")); | ||
} | ||
|
||
@Override | ||
public void run() { | ||
try { | ||
boolean exit = false; | ||
while (!(exit || this.isInterrupted())) { | ||
//noinspection BusyWait | ||
Thread.sleep(T1_SECONDS); | ||
boolean needDump = false; | ||
for (WeakReference<WatchdogTimer> watchdogTimerRef : this.watchdogTimers) { | ||
WatchdogTimer watchdogTimer = watchdogTimerRef.get(); | ||
if (watchdogTimer != null && watchdogTimer.isEnabled()) { | ||
long computingFor = watchdogTimer.getComputingFor(); | ||
if (computingFor / T1_SECONDS == 10L) { | ||
needDump = true; | ||
if (watchdogTimer.isEssential()) { | ||
exit = true; | ||
} | ||
} else if (computingFor / T1_SECONDS == 5L) { | ||
needDump = true; | ||
} | ||
} | ||
} | ||
if (needDump) { | ||
doCompleteThreadDump(exit); | ||
} | ||
} | ||
} catch (InterruptedException ignored) {} | ||
} | ||
|
||
static void registerTimer(WatchdogTimer watchdogTimer) { | ||
if (watchdogThread == null) { | ||
watchdogThread = new WatchdogThread(); | ||
watchdogThread.start(); | ||
} | ||
watchdogThread.watchdogTimers.add(new WeakReference<>(watchdogTimer)); | ||
} | ||
|
||
private void doCompleteThreadDump(boolean andExit) { | ||
if (System.currentTimeMillis() - this.lastStackDump < T1_9_SECONDS && !andExit) return; | ||
this.lastStackDump = System.currentTimeMillis(); | ||
System.out.println((andExit ? "Fatal freeze" : "Freeze") + " detected, creating stack dump:"); | ||
System.out.println(); | ||
for (Map.Entry<Thread, StackTraceElement[]> stackTrace : Thread.getAllStackTraces().entrySet()) { | ||
Thread thread = stackTrace.getKey(); | ||
System.out.println(thread.getName() + " (Priority: " + | ||
thread.getPriority() + (thread.isDaemon() ? ", Daemon)" : ")")); | ||
for (StackTraceElement stackTraceElement : stackTrace.getValue()) { | ||
System.out.println(" " + stackTraceElement.toString()); | ||
} | ||
System.out.println(); | ||
} | ||
if (andExit) { | ||
System.exit(1); | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
common/src/main/java/com/fox2code/foxloader/utils/WatchdogTimer.java
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package com.fox2code.foxloader.utils; | ||
|
||
public final class WatchdogTimer { | ||
private final boolean essential; | ||
private volatile long lastCheck; | ||
private volatile long megaLastCheck; | ||
private boolean enabled; | ||
|
||
public WatchdogTimer(boolean essential) { | ||
WatchdogThread.registerTimer(this); | ||
this.essential = essential; | ||
this.lastCheck = 0; | ||
this.megaHeartbeat(); | ||
this.enabled = true; | ||
} | ||
|
||
public boolean isEssential() { | ||
return this.essential; | ||
} | ||
|
||
long getComputingFor() { | ||
return this.lastCheck == 0 ? 0 : System.currentTimeMillis() - Math.max(this.lastCheck, this.megaLastCheck); | ||
} | ||
|
||
public void heartbeat() { | ||
this.lastCheck = System.currentTimeMillis(); | ||
} | ||
|
||
public void megaHeartbeat() { | ||
this.megaLastCheck = System.currentTimeMillis() + 10000L; | ||
} | ||
|
||
public boolean isEnabled() { | ||
return this.enabled; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
} |
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
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