mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-07-19 03:53:02 +01:00
WindowsProcessFeatures cleanup
- Adds logging around Open/Suspend/ResumeThread calls. - Call Process.Refresh before accessing Process.Threads, potentially fixing issues with a stale thead ID cache. - Potentially fixes #1279
This commit is contained in:
@@ -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 => { }));
|
||||
|
||||
Reference in New Issue
Block a user