Merge pull request #1282 from tgstation/1279-PotentialWindowsSuspendFix [TGSDeploy]

Potential fix for process suspension failure
This commit is contained in:
Jordan Brown
2021-06-14 22:46:22 -04:00
committed by GitHub
5 changed files with 34 additions and 6 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
<!-- Integration tests will ensure they match across the board -->
<Import Project="ControlPanelVersion.props" />
<PropertyGroup>
<TgsCoreVersion>4.12.0</TgsCoreVersion>
<TgsCoreVersion>4.12.1</TgsCoreVersion>
<TgsConfigVersion>3.0.0</TgsConfigVersion>
<TgsApiVersion>9.0.1</TgsApiVersion>
<TgsApiLibraryVersion>9.0.0</TgsApiLibraryVersion>
@@ -25,7 +25,7 @@ namespace Tgstation.Server.Host.System
/// <summary>
/// Resume a given suspended <see cref="Process"/>.
/// </summary>
/// <param name="process">The <see cref="Process"/> to susperesumend.</param>
/// <param name="process">The <see cref="Process"/> to suspended.</param>
void ResumeProcess(global::System.Diagnostics.Process process);
/// <summary>
@@ -7,6 +7,7 @@ using System.Threading;
using System.Threading.Tasks;
using BetterWin32Errors;
using Microsoft.Extensions.Logging;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Host.IO;
@@ -17,17 +18,37 @@ namespace Tgstation.Server.Host.System
/// <inheritdoc />
sealed class WindowsProcessFeatures : IProcessFeatures
{
/// <summary>
/// The <see cref="ILogger"/> for the <see cref="WindowsProcessFeatures"/>.
/// </summary>
readonly ILogger<WindowsProcessFeatures> logger;
/// <summary>
/// Initializes a new instance of the <see cref="WindowsProcessFeatures"/> class.
/// </summary>
/// <param name="logger">The value of logger.</param>
public WindowsProcessFeatures(ILogger<WindowsProcessFeatures> logger)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
/// <inheritdoc />
public void ResumeProcess(global::System.Diagnostics.Process process)
{
if (process == null)
throw new ArgumentNullException(nameof(process));
process.Refresh();
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = NativeMethods.OpenThread(NativeMethods.ThreadAccess.SuspendResume, false, (uint)thread.Id);
var threadId = (uint)thread.Id;
logger.LogTrace("Suspending thread {0}...", threadId);
var pOpenThread = NativeMethods.OpenThread(NativeMethods.ThreadAccess.SuspendResume, false, threadId);
if (pOpenThread == IntPtr.Zero)
{
logger.LogDebug(new Win32Exception(), "Failed to open thread {0}!", threadId);
continue;
}
try
{
@@ -47,11 +68,18 @@ namespace Tgstation.Server.Host.System
if (process == null)
throw new ArgumentNullException(nameof(process));
process.Refresh();
foreach (ProcessThread thread in process.Threads)
{
var pOpenThread = NativeMethods.OpenThread(NativeMethods.ThreadAccess.SuspendResume, false, (uint)thread.Id);
var threadId = (uint)thread.Id;
logger.LogTrace("Resuming thread {0}...", threadId);
var pOpenThread = NativeMethods.OpenThread(NativeMethods.ThreadAccess.SuspendResume, false, threadId);
if (pOpenThread == IntPtr.Zero)
{
logger.LogDebug(new Win32Exception(), "Failed to open thread {0}!", threadId);
continue;
}
try
{
if (NativeMethods.SuspendThread(pOpenThread) == UInt32.MaxValue)
@@ -21,7 +21,7 @@ namespace Tgstation.Server.Host.System.Tests
public void Init()
{
features = new PlatformIdentifier().IsWindows
? (IProcessFeatures)new WindowsProcessFeatures()
? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of<ILogger<WindowsProcessFeatures>>())
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => null), new DefaultIOManager(), Mock.Of<ILogger<PosixProcessFeatures>>());
}
@@ -227,7 +227,7 @@ namespace Tgstation.Server.Tests.Instance
IProcessExecutor executor = null;
executor = new ProcessExecutor(
new PlatformIdentifier().IsWindows
? (IProcessFeatures)new WindowsProcessFeatures()
? (IProcessFeatures)new WindowsProcessFeatures(Mock.Of<ILogger<WindowsProcessFeatures>>())
: new PosixProcessFeatures(new Lazy<IProcessExecutor>(() => executor), Mock.Of<IIOManager>(), Mock.Of<ILogger<PosixProcessFeatures>>()),
Mock.Of<ILogger<ProcessExecutor>>(),
LoggerFactory.Create(x => { }));