Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

possible to have a Timeout on ReadFile()?

Tags:

c++

windows

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?

like image 965
aCuria Avatar asked Oct 31 '10 12:10

aCuria


2 Answers

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.

like image 170
yonilevy Avatar answered Oct 02 '22 16:10

yonilevy


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);
    }
like image 43
C.D.H. Avatar answered Oct 02 '22 17:10

C.D.H.