pipes/PeekNamedPipe()/WaitForMultipleObjects() inconsistency

pipes/PeekNamedPipe()/WaitForMultipleObjects() inconsistency

Post by kiril » Sat, 06 Aug 2005 00:10:27

I have two processes (parent and child) that are connected via a
_pipe() created pipe that goes from parent to child's stdin. The parent
writes to the child using:
write(fd[1],..) fd[1] was created using _pipe(fd...)
the child reads using:
read(fileno(stdin), buff, 1)

I use WaitForMultipleObjects() on the child's side to detect if there's
stuff to read from stdin, and PeekNamedPipe() to double-check that
bytes are available. The problem is that sometimes PeekNamedPipe()
returns 0 bytes available even when the parent has clearly written
stuff to the pipe and WaitForMultipleObjects() has triggered!
Furthermore this happens inconsistently and at random places.

Which leads me to belive that its some kind of buffering issue. How can
I make sure that there is no buffering anywhere in the pipe, or how can
I flush the pipe in a consistent way? I tried setvbuf (stdin, ...
NOBUFF) on the child side and _commit() on the parent side, and a bunch
of other things, but all with limited success...

I've also tried the suggestion (by Phillip Crews on another group) to
PeekNamedPipe (..., &num_bytes_avail);
num_bytes_avail += stdin->_bufsiz - (DWORD)(sdtin->_ptr -

but this doesn't help - it still leads to a blocking on read() when
PNP() returns 0 and the second line adds a few bytes to it.

Do you have any other suggestions on how to consistently determin
whether I am ready to perform a non-blocking read of at least 1 byte
from stdin

Thanks a lot!

pipes/PeekNamedPipe()/WaitForMultipleObjects() inconsistency

Post by Eugene Ger » Sat, 06 Aug 2005 02:09:24

How do you use WaitForMultipleObjects? Do you have multiple threads reading
from the pipe?

Even without possible bugs I wouldn't rely on Wait functions alone to tell
that non-blocking read is possible. AFAIK there is no guarrantees in MSDN
about when exactly a pipe handle becomes signalled. So your double-check
with PeekNamedPipe seems to be a correct way of doing it. Why do you want to
avoid it?

If you really need asynchronous I/O consider dropping standard library
functions and using ReadFile[Ex] instead.