diff --git a/src/Tgstation.Server.Host.Watchdog/SignalChecker.cs b/src/Tgstation.Server.Host.Watchdog/SignalChecker.cs
new file mode 100644
index 0000000000..3be780fb39
--- /dev/null
+++ b/src/Tgstation.Server.Host.Watchdog/SignalChecker.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+using Microsoft.Extensions.Logging;
+
+using Mono.Unix;
+using Mono.Unix.Native;
+
+namespace Tgstation.Server.Host.Watchdog
+{
+ ///
+ /// Helper for checking POSIX signals.
+ ///
+ static class SignalChecker
+ {
+ ///
+ /// Forwards certain signals to a given .
+ ///
+ /// The to write to.
+ /// The of the process to forward signals to.
+ /// The for the operation.
+ /// A representing the running operation.
+ public static async Task CheckSignals(ILogger logger, int childPid, CancellationToken cancellationToken)
+ {
+ var signalTcs = new TaskCompletionSource();
+ async Task CheckSignal(Signum signum)
+ {
+ try
+ {
+ using var unixSignal = new UnixSignal(signum);
+ if (!unixSignal.IsSet)
+ {
+ logger.LogTrace("Waiting for {signum}...", signum);
+ while (!unixSignal.IsSet)
+ await Task.Delay(TimeSpan.FromMilliseconds(250), cancellationToken);
+
+ logger.LogTrace("{signum} received!", signum);
+ }
+ else
+ logger.LogDebug("{signum} has already been sent", signum);
+
+ signalTcs.TrySetResult(signum);
+ }
+ catch (OperationCanceledException)
+ {
+ }
+
+ return signum;
+ }
+
+ var tasks = new[]
+ {
+ CheckSignal(Signum.SIGUSR1),
+ CheckSignal(Signum.SIGUSR2),
+ };
+ var completedTask = await Task.WhenAny(tasks);
+ if (cancellationToken.IsCancellationRequested)
+ {
+ await Task.WhenAll(tasks);
+ return;
+ }
+
+ var signalReceived = await completedTask;
+ logger.LogInformation("Received {signalReceived}, forwarding to main TGS process!", signalReceived);
+ var result = Syscall.kill(childPid, signalReceived.Value);
+ if (result != 0)
+ logger.LogWarning(
+ new UnixIOException(Stdlib.GetLastError()),
+ "Failed to forward {signalReceived}!",
+ signalReceived);
+
+ // forward the other signal if necessary
+ await Task.WhenAll(tasks);
+ if (cancellationToken.IsCancellationRequested)
+ return;
+
+ var otherTask = tasks[0] == completedTask
+ ? tasks[1]
+ : tasks[0];
+
+ signalReceived = await otherTask;
+ logger.LogInformation("Received {signalReceived}, forwarding to main TGS process!", signalReceived);
+ result = Syscall.kill(childPid, signalReceived.Value);
+ if (result != 0)
+ logger.LogWarning(
+ new UnixIOException(Stdlib.GetLastError()),
+ "Failed to forward {signalReceived}!",
+ signalReceived);
+ }
+ }
+}
diff --git a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
index d8a1d580ed..1afd2cad85 100644
--- a/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
+++ b/src/Tgstation.Server.Host.Watchdog/Watchdog.cs
@@ -11,9 +11,6 @@ using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
-using Mono.Unix;
-using Mono.Unix.Native;
-
using Tgstation.Server.Host.Common;
namespace Tgstation.Server.Host.Watchdog
@@ -71,7 +68,8 @@ namespace Tgstation.Server.Host.Watchdog
{
// VS special tactics
// just copy the shit where it belongs
- Directory.Delete(assemblyStoragePath, true);
+ if (Directory.Exists(assemblyStoragePath))
+ Directory.Delete(assemblyStoragePath, true);
Directory.CreateDirectory(defaultAssemblyPath);
var sourcePath = "../../../../Tgstation.Server.Host/bin/Debug/net6.0";
@@ -128,8 +126,8 @@ namespace Tgstation.Server.Host.Watchdog
if (runConfigure)
{
- logger.LogInformation("Running configuration check and wizard if necessary...");
- arguments.Add("General:SetupWizardMode=Only");
+ logger.LogInformation("Running configuration check and wizard...");
+ arguments.Add("--General:SetupWizardMode=Only");
}
arguments.AddRange(args);
@@ -179,61 +177,19 @@ namespace Tgstation.Server.Host.Watchdog
}))
{
var processTask = tcs.Task;
- while (!processTask.IsCompleted)
+ using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
+
+ var checkerTask = isWindows
+ ? Task.CompletedTask
+ : SignalChecker.CheckSignals(logger, childPid, cts.Token);
+ try
{
- var signalTcs = new TaskCompletionSource();
- using var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
- async Task CheckSignal(Signum signum)
- {
- if (isWindows)
- return;
-
- try
- {
- using var unixSignal = new UnixSignal(signum);
- if (!unixSignal.IsSet)
- {
- logger.LogTrace("Waiting for {signum}...", signum);
- while (!unixSignal.IsSet)
- await Task.Delay(TimeSpan.FromMilliseconds(250), cts.Token);
-
- logger.LogTrace("{signum} received!", signum);
- }
- else
- logger.LogDebug("{signum} has already been sent", signum);
-
- signalTcs.TrySetResult(signum);
- }
- catch (OperationCanceledException)
- {
- }
- }
-
- var checkerTask = Task.WhenAll(
- CheckSignal(Signum.SIGUSR1),
- CheckSignal(Signum.SIGUSR2));
- try
- {
- var signalTask = signalTcs.Task;
-
- var completedTask = await Task.WhenAny(processTask, signalTask);
- if (completedTask == signalTask)
- {
- var signalReceived = await signalTask;
- logger.LogInformation("Received {signalReceived}, forwarding to main TGS process!", signalReceived);
- var result = Syscall.kill(childPid, signalReceived);
- if (result != 0)
- logger.LogWarning(
- new UnixIOException(Stdlib.GetLastError()),
- "Failed to forward {signalReceived}!",
- signalReceived);
- }
- }
- finally
- {
- cts.Cancel();
- await checkerTask;
- }
+ await processTask;
+ }
+ finally
+ {
+ cts.Cancel();
+ await checkerTask;
}
}
}
@@ -252,8 +208,19 @@ namespace Tgstation.Server.Host.Watchdog
process.WaitForExit();
}
}
- catch (InvalidOperationException)
+ catch (InvalidOperationException ex2)
{
+ logger.LogWarning(ex2, "Error killing host process!");
+ }
+
+ try
+ {
+ if (File.Exists(updateDirectory))
+ File.Delete(updateDirectory);
+ }
+ catch (Exception ex2)
+ {
+ logger.LogWarning(ex2, "Error deleting comms file!");
}
logger.LogInformation("Host exited!");