Add thread control surfaces
Adds RemoteThread, ThreadFactory (enumeration, main-thread selection, get-by-id), and FrozenThread scoped freeze. Supports suspend/resume, 32/64-bit context round-trip, TEB query, and reverse-order resume on dispose. Closes section 2 of add-thread-region-finder.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace WhiteMagic.Thread;
|
||||
|
||||
/// <summary>
|
||||
/// A disposable scope that tracks a set of threads frozen by <see cref="ThreadFactory.Freeze"/>.
|
||||
/// Disposing the scope resumes exactly those threads, in reverse order, even if the guarded
|
||||
/// body throws.
|
||||
/// </summary>
|
||||
public sealed class FrozenThread : IDisposable
|
||||
{
|
||||
private readonly IReadOnlyList<RemoteThread> _threads;
|
||||
private bool _disposed;
|
||||
|
||||
internal FrozenThread(IReadOnlyList<RemoteThread> threads)
|
||||
{
|
||||
_threads = threads ?? throw new ArgumentNullException(nameof(threads));
|
||||
}
|
||||
|
||||
/// <summary>The threads suspended by this freeze scope.</summary>
|
||||
public IEnumerable<RemoteThread> Threads => _threads;
|
||||
|
||||
/// <summary>
|
||||
/// Resumes the frozen threads in reverse order. The original call is responsible for
|
||||
/// disposing the <see cref="RemoteThread"/> instances afterwards.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_disposed = true;
|
||||
|
||||
foreach (RemoteThread thread in _threads.Reverse())
|
||||
{
|
||||
try
|
||||
{
|
||||
thread.Resume();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Resume-on-dispose is best-effort; callers keep the thread handles so
|
||||
// they can diagnose or recover separately.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user