zbenjamin

Hello,

is there a way to get a async notification from a named pipe handle that new data is available to read. A message or a event would be okay.
i know i can wait with ReadFile for available data. But if i want to use named pipes in a gui application with that would block my application loop.

regards zbenjamin



Re: Visual C++ General Async named pipe functions

Simple Samples

Look at the FILE_FLAG_OVERLAPPED mode in CreateNamedPipe. I think that will do what you need.






Re: Visual C++ General Async named pipe functions

zbenjamin

The FILE_FLAG_OVERLAPPED in CreateNamedPipe makes it possible for me to have async write and read operations. But what i need is a notification that new data is available. If i use overlapped i/o the read operation will return imediately when no data is available.
The examples in msdn only show code that blocks as long as no data is available.
What i need is a event/message that new data has arrived in a named pipe.
And i can not find a way to do it.




Re: Visual C++ General Async named pipe functions

Simple Samples

Look some more. You have not read enough. In particular, look at the OVERLAPPED structure; what is in it. Really; what you are asking for is there.






Re: Visual C++ General Async named pipe functions

zbenjamin

Thx for answering.
Okay i will look again into OVERLAPPED structure but i really looked many times on it and i can't find a way to do it right.
The best example for what i need is the WsaAsyncSelect function that is avaiable for sockets (but does sadly not work for named pipes). This function can activate a event when new data arrives in the socket.

Can you give me a simple example how you would do it
Afaik ReadFile has two ways of using it:
Async way: ReadFile will return immediately when no data is available.
Blocking way: ReadFile will wait until data is available.

So ReadFile is not the correct function to listen for a newDataAvailable Event.
The point is i cannot find the correct function to do it.

what i want to do is like that (pseudocode):

while(1)
{
event = waitForEvents();

if(event == newConnectionPending)
openConnection();
if(event == newDataAvailable)
readData(handleToCorrectPipe);
/*other events*/
}







Re: Visual C++ General Async named pipe functions

Simple Samples

Perhaps you are not familiar with WaitForMultipleObjects; look at it too.

Also see: http://search.msdn.microsoft.com/search/Default.aspx query=ReadFile+WaitForMultipleObjects&brand=msdn&locale=en-us&refinement=00&lang=en-us






Re: Visual C++ General Async named pipe functions

zbenjamin

I know the WaitForMultipleObjects function and according to msdn it can wait for:
  • Change notification
  • Console input
  • Event
  • Memory resource notification
  • Mutex
  • Process
  • Semaphore
  • Thread
  • Waitable timer
So there are no named pipes.
It can wait for events, yes but i have no function where i can specify the event for new data is available.
Hm i looked at your link (either i'm a idiot or i did not tell exactly what i need) but there were only examples where it is known when new data arrives. My code does not know when new data arrives in the named pipe it needs some notification.








Re: Visual C++ General Async named pipe functions


Re: Visual C++ General Async named pipe functions

zbenjamin

well yes your examples shows how to use a overlapped structure to monitor when a new connection comes in. Thats what i already know how to do:


OVERLAPPED op;
HANDLE h,
handleArray[2];
BOOL bStop = FALSE;

memset(&op, 0, sizeof(op));

--> create a event for monitoring new CONNECTIONS
handleArray[0] = op.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
handleArray[1] = gbl_hStopEvent;

while (bStop == FALSE)
{

-->create the named pipe or a new instance of a named pipe with overlapeed i/o
h = CreateNamedPipe(FILE_FLAG_OVERLAPPED);

-->connect named pipe returns immediately the overlapped structure tells
it that we want to do a async i/o operation
ConnectNamedPipe(h, &op);

-->now we wait for a new connection on the named pipe
switch (WaitForMultipleObjects(2, handleArray, FALSE, INFINITE))
{
case WAIT_OBJECT_0:
--> here is a new connection established
_beginthread(threadProc, 0, h);
ResetEvent(handleArray[0]);
break;

case WAIT_OBJECT_0 + 1:
CloseHandle(h);
bStop = TRUE;
break;
}

}

CloseHandle(handleArray[0]);

So new connection are NOT the problem. The problem i have is how do i know AFTER
ConnectNamedPipe told me a new connection is available that the client has send me new Data
WITHOUT using a blocking call to ReadFile or without having to poll the pipe.

regards benjamin




Re: Visual C++ General Async named pipe functions

Andreas Masur

Well...I thought it was clear from the description....nonetheless, take a look at the following:






Re: Visual C++ General Async named pipe functions

Simple Samples

Nearly everything I know about asynchronous IO I have learned from the MSDN. I know I searched the internet for at least one detail but I did it all myself. For those details you can ask in a forum or newsgroup. This forum is definitely not the appropriate place to ask this question, but the chances are that if you were to ask specific questions about details that are not clear in the documentaion, you will get more help here than I got elsewhere.

Yes, ReadFile will return immediately if you use overlapped IO but then you can wait on the event for data. Then when data is processed, do another ReadFile to wait for more data. Each wait can be for multiple events; one of the waits can be for messages. I am not sure how to do that in a message loop but it can be done if you want to do that.






Re: Visual C++ General Async named pipe functions

BarryTannenbaum

Create the named pipe with the FILE_FLAG_OVERLAPPED flag set, as previously described. Then create a thread which does the following:
  • Start an asynchronous read on the pipe.
  • Wait on the event handle in the OVERLAP structure.
  • When the event is signalled, use SendMessage to send your app a message indicating that information is available in the pipe. You need to use SendMessage (instead of PostMessage) since it's a synchrnous call and won't return until you've been notified of the message.
  • Loop back to the top.
Obviously there's error stuff here that I've left out. The details are left as an exercise for the reader. Smile

- Barry




Re: Visual C++ General Async named pipe functions

Simple Samples

BarryTannenbaum wrote:
Create the named pipe with the FILE_FLAG_OVERLAPPED flag set, as previously described. Then create a thread which does the following:
  • Start an asynchronous read on the pipe.
  • Wait on the event handle in the OVERLAP structure.
  • When the event is signalled, use SendMessage to send your app a message indicating that information is available in the pipe. You need to use SendMessage (instead of PostMessage) since it's a synchrnous call and won't return until you've been notified of the message.
  • Loop back to the top.

Obviously there's error stuff here that I've left out. The details are left as an exercise for the reader.

- Barry

That can work well if a separate worker thread is used, but it seems that it has not been established that a separate thread is being used. A separate worker thread is a good solution but it is my impression that zbenjamin does not want to do that.






Re: Visual C++ General Async named pipe functions

Andreas Masur

BarryTannenbaum wrote:
  • When the event is signalled, use SendMessage to send your app a message indicating that information is available in the pipe. You need to use SendMessage (instead of PostMessage) since it's a synchrnous call and won't return until you've been notified of the message.

Well...certainly you can skip the message part and simply handle the data right there in the thread...I know it is only a little detail but I do not like to waste unnecessary resources...





Re: Visual C++ General Async named pipe functions

Simple Samples

Andreas Masur wrote:

Well...certainly you can skip the message part and simply handle the data right there in the thread...I know it is only a little detail but I do not like to waste unnecessary resources...

I agree. I think we need to first determine if a separate thread will be used.