Processing (Windows): improves reliablity when terminating child process

This commit is contained in:
李通洲
2026-03-25 15:40:33 +08:00
parent 2d4a77b6f0
commit a1c5fe2bf2
2 changed files with 27 additions and 6 deletions
+16 -6
View File
@@ -140,6 +140,17 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle*
return NULL;
}
static void terminateChildProcess(HANDLE hProcess, HANDLE hChildPipeRead, HANDLE hReadEvent, IO_STATUS_BLOCK* piosb)
{
IO_STATUS_BLOCK cancelIosb = {};
if (NT_SUCCESS(NtCancelIoFileEx(hChildPipeRead, piosb, &cancelIosb)))
{
if (hReadEvent)
NtWaitForSingleObject(hReadEvent, TRUE, &(LARGE_INTEGER) { .QuadPart = -100000 }); // wait for cancellation to complete
}
NtTerminateProcess(hProcess, 1);
}
const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
{
assert(handle->pipeRead != INVALID_HANDLE_VALUE);
@@ -180,13 +191,13 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
break;
case STATUS_TIMEOUT:
CancelIo(hChildPipeRead);
TerminateProcess(hProcess, 1);
{
terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
return "NtReadFile(hChildPipeRead) timed out";
}
default:
CancelIo(hChildPipeRead);
TerminateProcess(hProcess, 1);
terminateChildProcess(hProcess, hChildPipeRead, hReadEvent, &iosb);
return "NtWaitForSingleObject(hReadEvent) failed";
}
}
@@ -196,8 +207,7 @@ const char* ffProcessReadOutput(FFProcessHandle* handle, FFstrbuf* buffer)
if (!NT_SUCCESS(status))
{
CancelIo(hChildPipeRead);
TerminateProcess(hProcess, 1);
terminateChildProcess(hProcess, hChildPipeRead, NULL, &iosb);
return "NtReadFile(hChildPipeRead) failed";
}
+11
View File
@@ -1373,3 +1373,14 @@ NTSYSAPI LOGICAL NTAPI RtlQueryPerformanceCounter(
NTSYSAPI LOGICAL NTAPI RtlQueryPerformanceFrequency(
_Out_ PLARGE_INTEGER PerformanceFrequency
);
NTSYSAPI NTSTATUS NTAPI NtCancelIoFileEx(
_In_ HANDLE FileHandle,
_In_opt_ PIO_STATUS_BLOCK IoRequestToCancel,
_Out_ PIO_STATUS_BLOCK IoStatusBlock
);
NTSYSAPI NTSTATUS NTAPI NtTerminateProcess(
_In_opt_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);