From f3e5a66a6c2ff6abc3d62250f2fdd6269f07f32a Mon Sep 17 00:00:00 2001 From: Viktor Szakats Date: Mon, 18 Aug 2025 10:28:42 +0200 Subject: [PATCH] processhelp.pm: use `Win32::Process*` perl modules if available `Win32::Process::List` and `Win32::Process`. To replace external calls to `tasklist.exe` and `taskkill.exe`. The perl modules are more efficient by not launching a command shell (including MSYS2) and an external process, then parse their output. According to local tests and the CI, one test session calls `tasklist.exe` 350-400 times. `taskkill.exe` is rarely called and often not called at all: https://github.com/curl/curl/actions/runs/17012376726?pr=18296 Cherry-picked from #18296 --- tests/processhelp.pm | 63 ++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/tests/processhelp.pm b/tests/processhelp.pm index 43513aae07..f1f8ef525a 100644 --- a/tests/processhelp.pm +++ b/tests/processhelp.pm @@ -29,6 +29,12 @@ use warnings; use Time::HiRes; +use pathhelp qw( + os_is_win + ); + +my $has_win32_process; + BEGIN { use base qw(Exporter); @@ -43,6 +49,18 @@ BEGIN { set_advisor_read_lock clear_advisor_read_lock ); + + if(os_is_win() && $^O ne 'MSWin32') { + $has_win32_process = eval { + no warnings "all"; + # https://metacpan.org/pod/Win32::Process + require Win32::Process; + # https://metacpan.org/pod/Win32::Process::List + require Win32::Process::List; + }; + } else { + $has_win32_process = 0; + } } use serverhelp qw( @@ -51,10 +69,6 @@ use serverhelp qw( datasockf_pidfilename ); -use pathhelp qw( - os_is_win - ); - use globalconfig qw( $dev_null ); @@ -114,11 +128,18 @@ sub pidexists { if($pid > 4194304 && os_is_win()) { $pid -= 4194304; if($^O ne 'MSWin32') { - my $filter = "PID eq $pid"; - # https://ss64.com/nt/tasklist.html - my $result = `tasklist -fi \"$filter\" 2>$dev_null`; - if(index($result, "$pid") != -1) { - return -$pid; + if($has_win32_process) { + my %processes = Win32::Process::List->new()->GetProcesses(); + if(exists $processes{$pid}) { + return -$pid; + } + } else { + my $filter = "PID eq $pid"; + # https://ss64.com/nt/tasklist.html + my $result = `tasklist -fi \"$filter\" 2>$dev_null`; + if(index($result, "$pid") != -1) { + return -$pid; + } } return 0; } @@ -145,10 +166,14 @@ sub pidterm { if($pid > 4194304 && os_is_win()) { $pid -= 4194304; if($^O ne 'MSWin32') { - # https://ss64.com/nt/taskkill.html - my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1"; - print "Executing: '$cmd'\n"; - system($cmd); + if($has_win32_process) { + Win32::Process::KillProcess($pid, 0); + } else { + # https://ss64.com/nt/taskkill.html + my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1"; + print "Executing: '$cmd'\n"; + system($cmd); + } return; } } @@ -170,10 +195,14 @@ sub pidkill { if($pid > 4194304 && os_is_win()) { $pid -= 4194304; if($^O ne 'MSWin32') { - # https://ss64.com/nt/taskkill.html - my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1"; - print "Executing: '$cmd'\n"; - system($cmd); + if($has_win32_process) { + Win32::Process::KillProcess($pid, 0); + } else { + # https://ss64.com/nt/taskkill.html + my $cmd = "taskkill -f -t -pid $pid >$dev_null 2>&1"; + print "Executing: '$cmd'\n"; + system($cmd); + } return; } }