#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2005
    Location
    North of the 49th Parallel
    Posts
    28
    Rep Power
    0

    [Win32] WaitForSingleObject on Named Pipe


    Hey everybody -

    I'm writing a small program that's supposed to use pipes (anonymous or named) as an IPC method. I'm having lots of trouble making the client wait for data to appear in the pipe.

    On Linux, this is easy - I just use select() and set an infinite time. That worked with no problems. On Windows, I'm using WaitForSingleObject() to make it wait. WaitForSingleObject() returns immediately and doesn't wait at all. ConnectNamedPipe() on the server side does wait, so I know the pipe is created and the client has opened it.

    Two questions:
    1) Does WaitForSingleObject() even work with named/anonymous pipes? If not, what function can I use?
    2) I'm using VS2003...sometimes compilers don't like certain functions. Is there something I need to know?

    My code follows.

    Server:
    Code:
    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HANDLE pipe;
    
    	LPCTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";
    
    	int x = 8 * 128 + 24;
    	DeleteFile( lpszPipename );
    	pipe = CreateNamedPipe( 
    			lpszPipename,       // pipe name 
    			PIPE_ACCESS_DUPLEX,     // read/write access 
    			PIPE_TYPE_BYTE |          // message type pipe 
    			PIPE_WAIT,              // blocking mode 
    			PIPE_UNLIMITED_INSTANCES, // max. instances  
    			x,                     // output buffer size 
    			x,                     // input buffer size 
    			200,                      // client time-out in msec
    			NULL ); 
    
    	BOOL fSuccess = ConnectNamedPipe( pipe, NULL );
    
    	system( "pause" );
    	return 0;
    }
    Client:
    Code:
    // NamedPipeClient.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	HANDLE pipe;
    
    	LPCTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe";
    
    	BOOL bWaitVal = WaitNamedPipe( lpszPipename, NMPWAIT_WAIT_FOREVER );
    
    	if( bWaitVal == FALSE ){
    		ExitFunction( "_tmain" );
    		return -1;
    	}
    
    	pipe = CreateFile( 
    		    lpszPipename,
    			GENERIC_READ,
    			FILE_SHARE_READ,
    			NULL,
    			OPEN_EXISTING,
    			FILE_ATTRIBUTE_NORMAL,
    			NULL );
    
    	DWORD dwWaitResult = WaitForSingleObject( pipe, INFINITE );
    
    	return 0;
    }
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2004
    Location
    NY,NY USA
    Posts
    260
    Rep Power
    11
    I don't think you can wait on a named pipe:

    http://msdn.microsoft.com/library/de...ngleobject.asp

    Check the bottom list of waitable 'things'. I don't see pipes listed there. Did you look at the msdn example pipe server?
    Maybe it can give you some ideas:

    http://msdn.microsoft.com/library/de...ipe_client.asp

    http://msdn.microsoft.com/library/de...ipe_client.asp
    Last edited by mark-w; September 21st, 2005 at 12:17 PM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2004
    Location
    NY,NY USA
    Posts
    260
    Rep Power
    11
    Also, if you just want to wait for the named pipe to come online, maybe you can replace your call to CreateFile() in your client app with CallNamedPipe():

    The CallNamedPipe function connects to a message-type pipe (and waits if an instance of the pipe is not available),


    http://msdn.microsoft.com/library/de...lnamedpipe.asp
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2005
    Location
    North of the 49th Parallel
    Posts
    28
    Rep Power
    0
    I looked through MSDN, several times.

    Turns out that I needed to add SYNCHRONIZE to the CreateNamedPipe call so it said

    Code:
    pipe = CreateNamedPipe( 
    			lpszPipename,       // pipe name 
    			PIPE_ACCESS_DUPLEX,     // read/write access 
    			PIPE_TYPE_BYTE |          // message type pipe 
    			PIPE_WAIT |              // blocking mode 
                            SYNCHRONIZE, 
    			PIPE_UNLIMITED_INSTANCES, // max. instances  
    			x,                     // output buffer size 
    			x,                     // input buffer size 
    			200,                      // client time-out in msec
    			NULL );
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2005
    Location
    North of the 49th Parallel
    Posts
    28
    Rep Power
    0
    I hate to necromance my own thread, but I'd rather show the code I had working so save time.

    The code above fails (or rather, WaitForSingleObject fails) when the above is run by two threads, not two processes. I originally tested it in two completely separate executables. Now that I want to run this within two threads in the same Windows DLL, WaitForSingleObject doesn't actually do any waiting.

    I've scoured the net, and spent countless hours on this in Visual Studio. I'm beginning to wonder if it has something to do with the way the HANDLEs are created. Are there issues with using HANDLEs in separate threads like I am?

    Thanks in advance.

IMN logo majestic logo threadwatch logo seochat tools logo