I'm trying to set a timeout to the reading operation of my named pipe.
In order to read from the named pipe, I'm using the ReadFile
function.
I read that a timeout can be set for this function with the SetCommTimeouts
function but when I try to use it, I get system error 1: "Incorrect function".
Here is my code (this is the client side):
m_pipe = CreateFileA(pipeName, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL); // no template file
if (m_pipe != INVALID_HANDLE_VALUE)
{
DWORD mode = PIPE_READMODE_MESSAGE | PIPE_WAIT;
ok = SetNamedPipeHandleState(m_pipe, &mode, NULL, NULL);
COMMTIMEOUTS cto;
cto.ReadTotalTimeoutConstant = 1000;
BOOL time = SetCommTimeouts(m_pipe, &cto);
}
Am I doing something wrong or the SetCommTimeouts
method is not supposed to be used with pipes? Is there any other way to get a reading timeout?
ReadFile blocks until it read requested amount of bytes or error/abort happen. Overlapped works same, i.e. it completes on same conditions. Tried to implement timeouts using CancelIoEx and figured out that it loses data. Until now see no way to implement timeouts and read only part of requested amount of bytes, or read cached data.
If the purpose of the timeout is to not get stuck
forever
you may consider a call to PeekNamedPipe(...) in a timed loop. This way you can check whether there is anything to read from time to time. AlternativelyPeekNamedPipe
may be used to decide whether a read on the pipe is actually going to get anything before the read is performed. This way a "waiting" read can be avoided.You cannot use SetCommTimeouts with named pipes. If you want timeouts, you will have to use Async I/O and implement the timeout yourself using
CancelIo
orCancelIoEx