Home > C/C++, Windows > Timeout on Named Pipes

Timeout on Named Pipes

Hi. In this post, I will show you how make a timeouted namedpipe with the WIN32 API: the msdn’s manual doesn’t explain how to do it.
The named pipes are an IPC’s method by which we can send data to an other process (like a son process).

This solution is useful when for example we have a parent process A that create a son process B. We want send data from A to B through the namedpipe. A has to create the namedpipe and connect to it. When A connects to the pipe, it waits until B opens the pipe allowing data transfer.
But, if B die before opening the pipe, then A will wait indefinitely.
To resolve this problem, we need to set a maximum timeout to wait at the end of which we are sure that there was some problem.

So, you have to create your namedpipe (msdn man) that you need:

	#define PIPE_NAME "test"

	...

	HANDLE hpipe;

	hPipe = CreateNamedPipe(
	  PIPE_NAME,                	// pipe name
	  PIPE_ACCESS_DUPLEX | 		// read/write access
	  FILE_FLAG_OVERLAPPED,
	  PIPE_TYPE_BYTE |          	// byte type pipe
	  PIPE_READMODE_BYTE |      	// message-read mode
	  PIPE_WAIT,               	// blocking mode
	  PIPE_UNLIMITED_INSTANCES, 	// max. instances
	  BUFSIZE,                  	// output buffer size
	  BUFSIZE,                  	// input buffer size
	  PIPE_TIMEOUT_CONNECT,        	// client time-out
	  NULL);                    	// default security attribute

In this example, I have created a namedpipe named PIPE_NAME, duplex, byte oriented, overlapped, etc..
Now we want to connect us to the namedpipe so we can send our data:


	#define PIPE_TIMEOUT_CONNECT 10000

	....

	OVERLAPPED ol = {0,0,0,0,NULL};
	BOOL ret = 0;

	ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	ret = ConnectNamedPipe(hPipe, &ol);

	if( ret == 0 ) {

		switch( GetLastError() ) {

			case ERROR_PIPE_CONNECTED:

				/* client is connected */
				ret = TRUE;

				break;

			case ERROR_IO_PENDING:

				/* if pending i wait PIPE_TIMEOUT_CONNECT ms */

				if( WaitForSingleObject(ol.hEvent, PIPE_TIMEOUT_CONNECT) == WAIT_OBJECT_0 ) {

					DWORD dwIgnore;

					ret = GetOverlappedResult(hPipe, &ol, &dwIgnore, FALSE);

				} else {

					CancelIo(hPipe);

				}

				break;
		}
	}

	CloseHandle(ol.hEvent);

	if( ret == 0 ) {

		return -1;
	}

	if ( WriteFile(hPipe, .... ) == 0 ) {

		return -1;

	}

So, what have we done?
In the line 8, we create a dummy event on which we will wait. In the line 10 we try to connect to the namedpipe “hpipe” using the ConnectNamedPipe() function (msdn man) . This function will return an error because we are using it in overlapped mode: so we have to check the type of error (line 14):

1 – ERROR_PIPE_CONNECTED: the client is connected;
2 – ERROR_IO_PENDING: we are waiting the client’s connection: we can wait PIPE_TIMEOUT_CONNECT ms (10 seconds) using the WaitForSingleObject() (msdn man) on the ol.hEvent. If the function succeed, we must just have to check the result of the GetOverlappedResult() (msdn man). Otherwise we delete all the I/O pending operations (msdn man).

At the end (line 45), if ret != 0, we can send our data through the WriteFile() function (line 45) (msdn man).
For any question, you can use comments. :-)
Bye.

About these ads
  1. Sreenivasula Reddy
    April 4, 2012 at 18:05

    Very much useful – clear explanation -really appreciated.
    Thanks

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: