std: Avoid deadlocking in ChildProcess.exec

Reading stdin&stderr at different times may lead to nasty deadlocks (eg.
when stdout is read before stderr and the child process doesn't write
anything onto stdout).

Implement a polling mechanism to make sure this won't happen: we read
data from stderr/stdout as it becomes ready and then it's copied into an
ArrayList provided by the user, avoiding any kind of blocking read.
This commit is contained in:
LemonBoy
2020-10-20 08:51:21 +02:00
committed by Andrew Kelley
parent 1590ed9d6a
commit dc810eb73b
3 changed files with 208 additions and 11 deletions

View File

@@ -438,6 +438,19 @@ pub const SECURITY_ATTRIBUTES = extern struct {
pub const PSECURITY_ATTRIBUTES = *SECURITY_ATTRIBUTES;
pub const LPSECURITY_ATTRIBUTES = *SECURITY_ATTRIBUTES;
pub const PIPE_ACCESS_INBOUND = 0x00000001;
pub const PIPE_ACCESS_OUTBOUND = 0x00000002;
pub const PIPE_ACCESS_DUPLEX = 0x00000003;
pub const PIPE_TYPE_BYTE = 0x00000000;
pub const PIPE_TYPE_MESSAGE = 0x00000004;
pub const PIPE_READMODE_BYTE = 0x00000000;
pub const PIPE_READMODE_MESSAGE = 0x00000002;
pub const PIPE_WAIT = 0x00000000;
pub const PIPE_NOWAIT = 0x00000001;
pub const GENERIC_READ = 0x80000000;
pub const GENERIC_WRITE = 0x40000000;
pub const GENERIC_EXECUTE = 0x20000000;

View File

@@ -15,6 +15,29 @@ pub extern "kernel32" fn CloseHandle(hObject: HANDLE) callconv(WINAPI) BOOL;
pub extern "kernel32" fn CreateDirectoryW(lpPathName: [*:0]const u16, lpSecurityAttributes: ?*SECURITY_ATTRIBUTES) callconv(WINAPI) BOOL;
pub extern "kernel32" fn SetEndOfFile(hFile: HANDLE) callconv(WINAPI) BOOL;
pub extern "kernel32" fn GetCurrentProcessId() callconv(.Stdcall) DWORD;
pub extern "kernel32" fn CreateNamedPipeA(
lpName: [*:0]const u8,
dwOpenMode: DWORD,
dwPipeMode: DWORD,
nMaxInstances: DWORD,
nOutBufferSize: DWORD,
nInBufferSize: DWORD,
nDefaultTimeOut: DWORD,
lpSecurityAttributes: ?*const SECURITY_ATTRIBUTES,
) callconv(.Stdcall) HANDLE;
pub extern "kernel32" fn CreateNamedPipeW(
lpName: LPCWSTR,
dwOpenMode: DWORD,
dwPipeMode: DWORD,
nMaxInstances: DWORD,
nOutBufferSize: DWORD,
nInBufferSize: DWORD,
nDefaultTimeOut: DWORD,
lpSecurityAttributes: ?*const SECURITY_ATTRIBUTES,
) callconv(.Stdcall) HANDLE;
pub extern "kernel32" fn CreateEventExW(
lpEventAttributes: ?*SECURITY_ATTRIBUTES,
lpName: [*:0]const u16,
@@ -32,6 +55,16 @@ pub extern "kernel32" fn CreateFileW(
hTemplateFile: ?HANDLE,
) callconv(WINAPI) HANDLE;
pub extern "kernel32" fn CreateFileA(
lpFileName: [*:0]const u8,
dwDesiredAccess: DWORD,
dwShareMode: DWORD,
lpSecurityAttributes: ?*const SECURITY_ATTRIBUTES,
dwCreationDisposition: DWORD,
dwFlagsAndAttributes: DWORD,
hTemplateFile: ?HANDLE,
) callconv(.Stdcall) HANDLE;
pub extern "kernel32" fn CreatePipe(
hReadPipe: *HANDLE,
hWritePipe: *HANDLE,