Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-blocking ConnectNamedPipe event not getting signaled

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???
    }
}
like image 838
links77 Avatar asked Jan 13 '13 18:01

links77


1 Answers

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.

like image 109
Anton Kovalenko Avatar answered Nov 14 '22 23:11

Anton Kovalenko