Понять, что в pipe больше нет и не будет данных
От: Aniskin  
Дата: 01.07.19 10:13
Оценка:
Есть консольное приложение, и я пытаюсь его вывод представить в виде объекта с одним методом Read (метод не обязан возвращать все запрашиваемые данные, но должен вернуть хотя бы 1 байт, 0 байт — конец потока).

  Код
function TdecStream.Read(AData: Pointer; ASize: Cardinal; AProcessedSize: PCardinal): HRESULT;
var
  ExitCode: DWORD;
  PipeAvailableSize: DWORD;
  Read: DWORD;
begin
    try
      Result := S_OK;
      if Assigned(AProcessedSize) then
        AProcessedSize^ := 0;
      if ASize = 0 then Exit;

      if not PeekNamedPipe(FChildStd_OUT_RD, nil, 0, nil, @PipeAvailableSize, nil) then
        RaiseLastOSError;

      if not GetExitCodeProcess(ProcessInformation.hProcess, ExitCode) then
        RaiseLastOSError;

      if ExitCode <> STILL_ACTIVE then
        if PipeAvailableSize = 0 then Exit;

      // Здесь есть гонка

      if PipeAvailableSize = 0 then
        PipeAvailableSize := 1;
      if ASize > PipeAvailableSize then
        ASize := PipeAvailableSize;
      if not ReadFile(FChildStd_OUT_RD, AData^, ASize, Read, nil) then
        RaiseLastOSError;
      if Assigned(AProcessedSize) then
        AProcessedSize^ := Read;

    except
      on E: Exception do
        Result := HResultFromException(E);
    end;
end;


Но есть проблема, которую я ни как не могу решить. Если дочерний процесс завершился, то ReadFile зависает навсегда, поскольку ждет данные из pipe. В коде есть попытка отловить статус STILL_ACTIVE, но возникает гонка, в которой процесс завершается после запроса состояния. Как мне корректно узнать, что в в pipe больше нет и не будет данных.
Re: Понять, что в pipe больше нет и не будет данных
От: reversecode google
Дата: 01.07.19 10:22
Оценка: 10 (2) +1
гуглить прежде чем спрашивать
https://what.thedailywtf.com/topic/25237/reading-stdout-with-winapi/5
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.