mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 00:22:40 +01:00
Use ThreadPool.WaitForSingleObject for SIGUSR1
This commit is contained in:
@@ -8,7 +8,6 @@ using Mono.Unix;
|
||||
using Mono.Unix.Native;
|
||||
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Utils;
|
||||
|
||||
namespace Tgstation.Server.Host.System
|
||||
{
|
||||
@@ -17,21 +16,11 @@ namespace Tgstation.Server.Host.System
|
||||
/// </summary>
|
||||
sealed class PosixSignalHandler : IHostedService, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Check for signals each time this amount of milliseconds pass.
|
||||
/// </summary>
|
||||
const int CheckDelayMs = 250;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IServerControl"/> for the <see cref="PosixSignalHandler"/>.
|
||||
/// </summary>
|
||||
readonly IServerControl serverControl;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="IAsyncDelayer"/> for the <see cref="PosixSignalHandler"/>.
|
||||
/// </summary>
|
||||
readonly IAsyncDelayer asyncDelayer;
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ILogger"/> for the <see cref="PosixSignalHandler"/>.
|
||||
/// </summary>
|
||||
@@ -51,12 +40,10 @@ namespace Tgstation.Server.Host.System
|
||||
/// Initializes a new instance of the <see cref="PosixSignalHandler"/> class.
|
||||
/// </summary>
|
||||
/// <param name="serverControl">The value of <see cref="serverControl"/>.</param>
|
||||
/// <param name="asyncDelayer">The value of <see cref="asyncDelayer"/>.</param>
|
||||
/// <param name="logger">The value of <see cref="logger"/>.</param>
|
||||
public PosixSignalHandler(IServerControl serverControl, IAsyncDelayer asyncDelayer, ILogger<PosixSignalHandler> logger)
|
||||
public PosixSignalHandler(IServerControl serverControl, ILogger<PosixSignalHandler> logger)
|
||||
{
|
||||
this.serverControl = serverControl ?? throw new ArgumentNullException(nameof(serverControl));
|
||||
this.asyncDelayer = asyncDelayer ?? throw new ArgumentNullException(nameof(asyncDelayer));
|
||||
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
|
||||
cancellationTokenSource = new CancellationTokenSource();
|
||||
@@ -100,17 +87,23 @@ namespace Tgstation.Server.Host.System
|
||||
logger.LogTrace("Started SignalChecker");
|
||||
|
||||
using var unixSignal = new UnixSignal(Signum.SIGUSR1);
|
||||
if (!unixSignal.IsSet)
|
||||
{
|
||||
logger.LogTrace("Waiting for SIGUSR1...");
|
||||
var cancellationToken = cancellationTokenSource.Token;
|
||||
while (!unixSignal.IsSet)
|
||||
await asyncDelayer.Delay(TimeSpan.FromMilliseconds(CheckDelayMs), cancellationToken);
|
||||
logger.LogTrace("Waiting for SIGUSR1...");
|
||||
var cancellationToken = cancellationTokenSource.Token;
|
||||
|
||||
logger.LogTrace("SIGUSR1 received!");
|
||||
var tcs = new TaskCompletionSource();
|
||||
using (cancellationToken.Register(() => tcs.TrySetCanceled(cancellationToken)))
|
||||
{
|
||||
ThreadPool.RegisterWaitForSingleObject(
|
||||
unixSignal,
|
||||
(o, timeout) => tcs.TrySetResult(),
|
||||
null,
|
||||
Timeout.Infinite,
|
||||
true);
|
||||
|
||||
await tcs.Task;
|
||||
}
|
||||
else
|
||||
logger.LogDebug("SIGUSR1 has already been sent");
|
||||
|
||||
logger.LogTrace("SIGUSR1 received!");
|
||||
|
||||
logger.LogTrace("Triggering graceful shutdown...");
|
||||
await serverControl.GracefulShutdown();
|
||||
|
||||
@@ -9,7 +9,6 @@ using Moq;
|
||||
using Tgstation.Server.Host.Core;
|
||||
using Tgstation.Server.Host.Extensions;
|
||||
using Tgstation.Server.Host.System;
|
||||
using Tgstation.Server.Host.Utils;
|
||||
|
||||
namespace Tgstation.Server.Host.Tests.Signals
|
||||
{
|
||||
@@ -25,9 +24,7 @@ namespace Tgstation.Server.Host.Tests.Signals
|
||||
.Callback(() => tcs.SetResult())
|
||||
.Returns(Task.CompletedTask);
|
||||
|
||||
var mockAsyncDelayer = new Mock<IAsyncDelayer>();
|
||||
mockAsyncDelayer.Setup(x => x.Delay(It.IsAny<TimeSpan>(), It.IsAny<CancellationToken>())).Returns(Task.CompletedTask);
|
||||
using var signalHandler = new PosixSignalHandler(mockServerControl.Object, mockAsyncDelayer.Object, Mock.Of<ILogger<PosixSignalHandler>>());
|
||||
using var signalHandler = new PosixSignalHandler(mockServerControl.Object, Mock.Of<ILogger<PosixSignalHandler>>());
|
||||
|
||||
Assert.IsFalse(tcs.Task.IsCompleted);
|
||||
|
||||
@@ -43,7 +40,7 @@ namespace Tgstation.Server.Host.Tests.Signals
|
||||
await signalHandler.StopAsync(default).WithToken(cts.Token);
|
||||
Assert.IsFalse(tcs.Task.IsCompleted);
|
||||
|
||||
using var signalHandler2 = new PosixSignalHandler(mockServerControl.Object, mockAsyncDelayer.Object, Mock.Of<ILogger<PosixSignalHandler>>());
|
||||
using var signalHandler2 = new PosixSignalHandler(mockServerControl.Object, Mock.Of<ILogger<PosixSignalHandler>>());
|
||||
await signalHandler2.StartAsync(default);
|
||||
|
||||
using var cts2 = new CancellationTokenSource(TimeSpan.FromSeconds(20));
|
||||
|
||||
@@ -20,15 +20,12 @@ namespace Tgstation.Server.Host.System.Tests
|
||||
[TestMethod]
|
||||
public void TestConstruction()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new PosixSignalHandler(null, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new PosixSignalHandler(null, null));
|
||||
|
||||
var mockServerControl = Mock.Of<IServerControl>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new PosixSignalHandler(mockServerControl, null, null));
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new PosixSignalHandler(mockServerControl, null));
|
||||
|
||||
var mockAsyncDelayer = Mock.Of<IAsyncDelayer>();
|
||||
Assert.ThrowsException<ArgumentNullException>(() => new PosixSignalHandler(mockServerControl, mockAsyncDelayer, null));
|
||||
|
||||
new PosixSignalHandler(mockServerControl, mockAsyncDelayer, Mock.Of<ILogger<PosixSignalHandler>>()).Dispose();
|
||||
new PosixSignalHandler(mockServerControl, Mock.Of<ILogger<PosixSignalHandler>>()).Dispose();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
Reference in New Issue
Block a user