diff --git a/TGServerService/ServerInstance/DreamDaemon.cs b/TGServerService/ServerInstance/DreamDaemon.cs
index ad7ba5f673..d84400edc1 100644
--- a/TGServerService/ServerInstance/DreamDaemon.cs
+++ b/TGServerService/ServerInstance/DreamDaemon.cs
@@ -10,7 +10,7 @@ using TGServiceInterface.Components;
namespace TGServerService
{
//manages the dd window.
- //It's not possible to actually click it while starting it in CL mode, so in order to change visibility etc. It restarts the process when the round ends
+ //It's not possible to actually click it while starting it in CL mode, so in order to change visibility, security, etc. It restarts the process when the world reboots
sealed partial class ServerInstance : ITGDreamDaemon
{
enum ShutdownRequestPhase
@@ -20,29 +20,79 @@ namespace TGServerService
Pinged,
}
+ ///
+ /// Directory for storing DreamDaemon diagnostic files
+ ///
const string DiagnosticsDir = "Diagnostics";
+ ///
+ /// Directory for storing DreamDaemon ResourceUsage files
+ ///
const string ResourceDiagnosticsDir = DiagnosticsDir + "/Resources";
+ ///
+ /// Time until DD is considered DOA on startup
+ ///
const int DDHangStartTime = 60;
+ ///
+ /// If DreamDaemon crashes before this time it is considered a bad startup
+ ///
const int DDBadStartTime = 10;
+ ///
+ /// The DreamDaemon process
+ ///
Process Proc;
+ ///
+ /// CPU performance information for
+ ///
PerformanceCounter pcpu;
+ ///
+ /// Used for multithreading safety
+ ///
object watchdogLock = new object();
+ ///
+ /// The thread that monitors the status of DreamDaemon
+ ///
Thread DDWatchdog;
+ ///
+ /// The of
+ ///
DreamDaemonStatus currentStatus;
+ ///
+ /// Current logfile in use in
+ ///
string CurrentDDLog;
+ ///
+ /// Current port DreamDaemon is running on
+ ///
ushort currentPort = 0;
+ ///
+ /// Used for multithreading safety
+ ///
object restartLock = new object();
+ ///
+ /// Used to indicate if an intentional restart is in progress on the watchdog. Requires to access
+ ///
bool RestartInProgress = false;
+ ///
+ /// Used to indicate if an service restart is in progress on the watchdog. Requires to access
+ ///
bool ReattachInsteadOfRestart = false;
+ ///
+ /// Current level of DreamDaemon
+ ///
DreamDaemonSecurity StartingSecurity;
+ ///
+ /// Indicator of progress on a or operation
+ ///
ShutdownRequestPhase AwaitingShutdown;
- //Only need 1 proc instance
+ ///
+ /// Setup or reattach the watchdog, depending on , and create the
+ ///
void InitDreamDaemon()
{
Directory.CreateDirectory(DiagnosticsDir);
@@ -62,8 +112,11 @@ namespace TGServerService
});
//start wd
- RestartInProgress = true;
- ReattachInsteadOfRestart = true;
+ lock (restartLock)
+ {
+ RestartInProgress = true;
+ ReattachInsteadOfRestart = true;
+ }
currentPort = Properties.Settings.Default.ReattachPort;
serviceCommsKey = Properties.Settings.Default.ReattachCommsKey;
try
@@ -100,7 +153,9 @@ namespace TGServerService
ThreadPool.QueueUserWorkItem( _ => { Start(); });
}
- //die now k thx
+ ///
+ /// Either let go of for reattachment or terminate it, depending on
+ ///
void DisposeDreamDaemon()
{
var Detach = Properties.Settings.Default.ReattachToDD;
@@ -227,6 +282,10 @@ namespace TGServerService
return res;
}
+ ///
+ /// Write a to the . A timestamp will be prepended to it
+ ///
+ /// The message to log
void WriteCurrentDDLog(string message)
{
lock (watchdogLock)
@@ -237,7 +296,9 @@ namespace TGServerService
}
}
- //loop that keeps the server running
+ ///
+ /// Threaded loop that keeps DreamDaemon from unintentionally stopping
+ ///
void Watchdog()
{
try
@@ -339,7 +400,10 @@ namespace TGServerService
Properties.Settings.Default.ReattachPID = Proc.Id;
Properties.Settings.Default.ReattachPort = currentPort;
Properties.Settings.Default.ReattachCommsKey = serviceCommsKey;
- RestartInProgress = true;
+ lock (restartLock)
+ {
+ RestartInProgress = true;
+ }
}
Proc.Close();
}
@@ -358,18 +422,26 @@ namespace TGServerService
currentStatus = DreamDaemonStatus.Offline;
currentPort = 0;
AwaitingShutdown = ShutdownRequestPhase.None;
- if (!RestartInProgress)
+ lock (restartLock)
{
- if(!Properties.Settings.Default.ReattachToDD)
- SendMessage("DD: Server stopped, watchdog exiting...", MessageType.WatchdogInfo);
- Service.WriteInfo("Watch dog exited", EventID.DDWatchdogExit);
+ if (!RestartInProgress)
+ {
+ if (!Properties.Settings.Default.ReattachToDD)
+ SendMessage("DD: Server stopped, watchdog exiting...", MessageType.WatchdogInfo);
+ Service.WriteInfo("Watch dog exited", EventID.DDWatchdogExit);
+ }
+ else
+ Service.WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart);
}
- else
- Service.WriteInfo("Watch dog restarting...", EventID.DDWatchdogRestart);
}
}
}
+ ///
+ /// Called every five seconds while DreamDaemon is running to log it's current state to the
+ ///
+ /// The event sender, an instance of
+ /// The
private void MemTrackTimer_Elapsed(object sender, ElapsedEventArgs e)
{
ulong megamem;
@@ -386,14 +458,6 @@ namespace TGServerService
///
public string CanStart()
- {
- lock (watchdogLock)
- {
- return CanStartImpl();
- }
- }
-
- string CanStartImpl()
{
if (GetVersion(ByondVersion.Installed) == null)
return "Byond is not installed!";
@@ -416,7 +480,7 @@ namespace TGServerService
{
if (currentStatus != DreamDaemonStatus.Offline)
return "Server already running";
- var res = CanStartImpl();
+ var res = CanStart();
if (res != null)
return res;
currentPort = 0;
@@ -424,8 +488,12 @@ namespace TGServerService
}
return StartImpl(false);
}
-
- //translate the configured security level into a byond param
+
+ ///
+ /// Translate the configured level into a byond command line param
+ ///
+ /// If bases it's result on , uses otherwise
+ /// "safe", "trusted", or "ultrasafe" depending on the it checks
string SecurityWord(bool starting = false)
{
var level = starting ? StartingSecurity : (DreamDaemonSecurity)Properties.Settings.Default.ServerSecurity;
@@ -442,6 +510,10 @@ namespace TGServerService
}
}
+ ///
+ /// Copies from the program directory to the the directory
+ ///
+ /// If , overwrites the 's current interface .dll if it exists
void UpdateInterfaceDll(bool overwrite)
{
if (File.Exists(InterfaceDLLName) && !overwrite)
@@ -451,14 +523,18 @@ namespace TGServerService
File.Copy(InterfacePath, InterfaceDLLName, overwrite);
}
- //used by Start and Watchdog to start a DD instance
+ ///
+ /// Clears the current , calls with a parameter, and attempts to start the DreamDaemon
+ ///
+ /// If , sets to a new pointing to and starts it
+ /// on success, error message on failure
string StartImpl(bool watchdog)
{
try
{
lock (watchdogLock)
{
- var res = CanStartImpl();
+ var res = CanStart();
if (res != null)
return res;