aCuria
aCuria

Reputation: 7215

possible to have a Timeout on ReadFile()?

while(GetExitCodeProcess(processInfo.hProcess, &exitCode)
        && exitCode == STILL_ACTIVE)
{
    ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0);
    WriteFile(writingEnd, chBuf, 1, &dwWritten, 0);
}

The problem with the code above is that even when the child process referenced through processInfo.hProcess has exited, we are still stuck in the while loop because ReadFile() is waiting for input. Whats the best way to solve this?

Upvotes: 8

Views: 18257

Answers (2)

C.D.H.
C.D.H.

Reputation: 101

It is possible to assume a timeout with a non-overlapped ReadFile, but indirectly.

First you must set the timeouts for the handle using SetCommTimeouts specifically there has to at least be a value set to the ReadTotalTimeoutConstant passed to this function. (One caveat: This works when your handle points to a comm port, not sure how it might work if that is actually a file being read.)

With that set up appropriately the ReadFile function will kick out either when its done filling its buffer, reaches end of file, or when it reaches the timeout. its not going to throw any errors or anything so to determine that a timeout occured you need to compare your &dwRead to the number of expected bytes. since you are only looking for 1 byte, if dwRead = 0 then you had a timeout, and not an end of file.

So the way I'd write it (and I can't claim that I'm following best practices or anything) is to do the following:

    COMMTIMEOUTS timeouts = { 0, //interval timeout. 0 = not used
                              0, // read multiplier
                             10, // read constant (milliseconds)
                              0, // Write multiplier
                              0  // Write Constant
                            };


    SetCommTimeouts(defaultSTDIN, &timeouts);

    while(GetExitCodeProcess(processInfo.hProcess, &exitCode)
          && exitCode == STILL_ACTIVE)
    {
        ReadFile(defaultSTDIN, chBuf, 1, &dwRead, 0);
        if (dwRead == 0) {
                     //insert code to handle timeout here
        }
        WriteFile(writingEnd, chBuf, 1, &dwWritten, 0);
    }

Upvotes: 8

yonilevy
yonilevy

Reputation: 5428

What you need is to read the file asynchronously using the FILE_FLAG_OVERLAPPED flag when opening the file, and specifying an OVERLAPPED structure to the ReadFile function. Then you could wait on both the read operation and the process termination, and act appropriately.

Upvotes: 11

Related Questions