Severity: Info
File
src/Servy.Core/Helpers/ProcessKiller.cs
Lines
217 + 219, 270 + 287
Issue
Both overloads of KillProcessTreeAndParents call two separate native snapshot enumerations of the entire system process table:
// Line 217-219 — KillProcessTreeAndParents(string processName, ...)
var completeSnapshot = BuildProcessSnapshotNative(); // CreateToolhelp32Snapshot + Process32First/Next over all PIDs
var protectedPids = GetAncestorPids(completeSnapshot);
var byParent = BuildParentChildMapNative(); // CreateToolhelp32Snapshot + Process32First/Next over all PIDs (again!)
BuildProcessSnapshotNative returns Dictionary<int, ProcessInfoNode> { ParentId, Name }, while BuildParentChildMapNative returns Dictionary<int, List<int>> (parent → children). Both are derived from the same PROCESSENTRY32 rows — they could be built in a single pass.
On a busy server with 500+ processes this is a measurable redundant native call (CreateToolhelp32Snapshot itself is non-trivial under load) and during process-kill work it widens the race window between the two snapshots — they may disagree about which PIDs exist, causing KillParentProcesses to refuse a parent that WalkAndKillChildren is also trying to handle.
Suggested fix
Add a single BuildSnapshot (or extend BuildProcessSnapshotNative) that returns both maps from one Toolhelp32 walk:
private (Dictionary<int, ProcessInfoNode> snapshot, Dictionary<int, List<int>> byParent)
BuildSnapshotAndChildMap()
{
// single CreateToolhelp32Snapshot pass, populate both
}
Then have KillProcessTreeAndParents consume both from one call instead of issuing two snapshots.
Severity: Info
File
src/Servy.Core/Helpers/ProcessKiller.csLines
217 + 219, 270 + 287
Issue
Both overloads of
KillProcessTreeAndParentscall two separate native snapshot enumerations of the entire system process table:BuildProcessSnapshotNativereturnsDictionary<int, ProcessInfoNode> { ParentId, Name }, whileBuildParentChildMapNativereturnsDictionary<int, List<int>>(parent → children). Both are derived from the samePROCESSENTRY32rows — they could be built in a single pass.On a busy server with 500+ processes this is a measurable redundant native call (
CreateToolhelp32Snapshotitself is non-trivial under load) and during process-kill work it widens the race window between the two snapshots — they may disagree about which PIDs exist, causingKillParentProcessesto refuse a parent thatWalkAndKillChildrenis also trying to handle.Suggested fix
Add a single
BuildSnapshot(or extendBuildProcessSnapshotNative) that returns both maps from one Toolhelp32 walk:Then have
KillProcessTreeAndParentsconsume both from one call instead of issuing two snapshots.