Andy 2009-09-20 02:05:13
I am porting a Unix program which uses poll() on sockets and pipes. So
I’m doing this with WaitForMultipleObjects(). The sockets appear to
work fine (using WSAEvents), but pipes do not work out.
What is the proper way to wait() on a pipe? Looking around, the only
thing I can take a guess at would have to be “overlapped” I/O (whatever
that means), and that does not look feasible for the way my program is
I tried creating a named pipe instead of an anonymous one. Didn’t
work. I guess I could create an AF_UNIX socket, but that seems to me a
little bit wasteful and awkward. Is there any way I can do it on an
For such a straightforward feature it’s amazing that this isn’t simple
Sarge 2009-09-20 02:05:17
Since Windows apps are event-driven, it is difficult to simulate a poll()
with file handles that are intended to be used with Overlapped I/O.
Unfortunately, the proper way to use named pipes is to listen for
connections on one thread, and use an I/O Completion Port to handle the
overlapped completions of ReadFile()s and WriteFile()s issued on the client
pipes. Socket servers and named pipe apps are very difficult to port from
unix to windows, without completely changing the program’s logic and
Sten westerbac 2009-09-20 02:05:32
It can easily be seen from documentation of WaitFor* functions that
named pipes are not waitable.
If you refer to waiting for someone to connect to your pipe instance,
then you use ConnectNamedPipe().
If you mean waiting for something to read, ReadFile() is the solution.
If you want to peek to see if something is available, use
PeekNamedPipe() which despite it’s name also works with anonymous pipes.
I though you said you were rewriting it…. 😉
I’m not familiar with other poll()’s but the DirectX one
but it seems like PeekNamedPipe() + some Sleep() would do it.
IMHO it is simple and intuitive… but i wouldn’t have minded if they
would have made it possible to wait for it with WaitMultipleObject().
But usually you handle each pipe with it’s own thread…
Andy 2009-09-23 15:19:57
This is a good suggestion. It works well for my purposes, except that
now I can’t detect EOF. Hmm.. Back to the drawing board. Any tips?
It just seems like they got the inheritance (in the OO sense of the
word) concept all wrong. If you are going to create a bunch of
typedefs for different kinds of HANDLEs you might as well make them act
the same. Certainly, if you’re making a function as generic as
WaitForMultipleObjects(), you should try to make things consistent. A
pipe, a socket, etc. all “inherit” from HANDLE. They should act
similarly on a call to a generic HANDLE.
Just strikes me as very brain-dead. “A pipe is a HANDLE, but only if
you use it this way….”
But. Excuse me for this rant. I tend to think with a Unix point of
Sten westerbac 2009-09-23 15:20:08
EOF would probably close the other end of the pipe.. and both
and ReadFile() will fail and you can CloseHandle() etc…
You seem to have slightly inproper idea about handles. It’s not “pipe is
but instead “HANDLE happen to point to kernel object with happens to be a
So a HANDLE points at ANYTHING in the kernel and MS can choose what
type of kernel objects any certain user mode (like WaitFor*Object()) can
kernel mode and successfully use…
But i guess Microsoft had difficulty making up their mind would it be
one byte has arrived, when 1kB has arrived, when the other end has been
or perhaps when the write buffer on a duplex pipe has become empty or
But they could provide a function such as…
SetKernelObjectSignallingMode(hPipe, -1, -1,
Andy 2009-09-23 15:20:38
For a moment my program seemed like PeekNamedPipe() wasn’t doing
that… However, I looked into it and it turns out EOF wasn’t getting
caught due to some other part of the code.
All is working now. Thanks for your help.