I am starting out with named pipes and need to use them for IPC between two local processes. I have both the server and client process using the pipe in nonblocking overlapped mode.
Everything works fine (the server successfully receives a string sent by the client) except that the event passed to ConnectNamedPipe() via the OVERLAPPED structure is not getting signaled as expected (signaled when a client connects).
While the server is blocked on the WaitForSingleObject() call the client process connected to the pipe, sent its data and terminated yet the event does not get signaled. What am I missing?
Server code:
HANDLE hPipe = ::CreateNamedPipeW(
L"\\\\.\\pipe\\ThePipe",
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT,
1,
4096,
4096,
100,
nullptr);
OVERLAPPED ov = {0};
ov.hEvent = ::CreateEventW(nullptr, TRUE, FALSE, nullptr);
BOOL retVal = ::ConnectNamedPipe(hPipe, &ov);
if (retVal == 0)
{
DWORD err = ::GetLastError();
if (err == ERROR_IO_PENDING)
{
::WaitForSingleObject(ov.hEvent, 30000);
}
if (err == ERROR_PIPE_LISTENING)
{
::WaitForSingleObject(ov.hEvent, 30000); // this blocks until time-out???
}
}
You shouldn't use (deprecated) PIPE_NOWAIT
together with overlapped mode. PIPE_NOWAIT
makes ConnectNamedPipe
immediately return ERROR_PIPE_LISTENING
if no client is connected; overlapped I/O just doesn't happen, and waiting for event is useless.
Either you set PIPE_NOWAIT
and poll the pipe periodically until success, or you set FILE_FLAG_OVERLAPPED
and use an event to check/wait for completion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With