Solved

select and WaitForMultipleObjects

Posted on 1998-06-29
10
2,326 Views
Last Modified: 2013-12-03
Hello,

I'm writing a small program that needs to wait on socket I/O and on process I/O using pipes.

To detect pipe I/O I must use WaitForMultipleObjects and for socket I/O I must use select.
These waits are incompatible. I can't even interrupt one if there is data to forward bewteen them.
Is there a way to use select or WaitForMultipleObjects to wait for all types of event without needing to poll ?

Do I have to go for threads where I could avoid it in unix ?


0
Comment
Question by:meessen
  • 7
  • 3
10 Comments
 
LVL 2

Accepted Solution

by:
abesoft earned 50 total points
ID: 1408904
:From the docs:
The Microsoft implementation of Windows Sockets allows socket handles to be treated as file handles. That is, it is possible to use socket handles with ReadFile, WriteFile, ReadFileEx, WriteFileEx, DuplicateHandle, and other Win32 functions. For an application to run over non-Microsoft implementations of Windows Sockets, socket handles should not be used with the Win32 functions that expect file handles, or an alternate code path should be provided.
:End of Docs:

So, this would seem to imply that you could DuplicateHandle on your socket handle to get a proper handle that you could WaitForMultipleEvents on.
0
 
LVL 1

Author Comment

by:meessen
ID: 1408905
The good news is that I use Windows socket implementation.

I created a listening socket and passed it to WaitFor MultipleObjects but apparently the object doesn't become signaled when a connection is done. So I stay with a pending connection. This might be THE exception.

It would be great if I could wait for incomming connections,socket I/O, child processes death and child process I/o through pipe in a single call.

Unfortunately the incomming connection did never signaled the object so I did not test the rest. It's useless unless you can confirm to me that it should work and the problem might be in my code.

Beside I need to port this beast on unix.
0
 
LVL 1

Author Comment

by:meessen
ID: 1408906
The good news is that I use Windows socket implementation.

I created a listening socket and passed it to WaitFor MultipleObjects but apparently the object doesn't become signaled when a connection is done. So I stay with a pending connection. This might be THE exception.

It would be great if I could wait for incomming connections,socket I/O, child processes death and child process I/o through pipe in a single call.

Unfortunately the incomming connection did never signaled the object so I did not test the rest. It's useless unless you can confirm to me that it should work and the problem might be in my code.

Beside I need to port this beast on unix.
0
Salesforce Made Easy to Use

On-screen guidance at the moment of need enables you & your employees to focus on the core, you can now boost your adoption rates swiftly and simply with one easy tool.

 
LVL 1

Author Comment

by:meessen
ID: 1408907
I checked again for WaitFor... with a listening socket and it doesn't work. It works well with select.

Select signals an error when given a Process handle or a pipe handle. This behaves as documented.

And the answer is .....

WSAEventSelect !

This makes my code portable ! Great !


0
 
LVL 1

Author Comment

by:meessen
ID: 1408908
Well of course WSAEventSelect is documented but is not provided in the library and most probably not implemented. Thank you M$...

Any other idea ?
0
 
LVL 1

Author Comment

by:meessen
ID: 1408909
Now suppose I want to use two threads. select is used for socket io thread.
And WaitFor... in a child process listening thread.
I could use event objects to unblock a WaitFor when network data has come in.
But how do I unblock a select ?

This means that the WaitFor... must do the socket send using non blocking calls.

Excuuuse me be this is getting really twisted for what look like a very simple and academic application. And we can definitively forget about protability here.

I'm desperate... and this work is soo urgent as usual !
0
 
LVL 2

Expert Comment

by:abesoft
ID: 1408910
If you want portable code, have you considered using ACE?  It is a library that encapsulates a lot of multiprocessing and communications concepts, and is quite extensive.  Check out http://www.cs.wustl.edu/~schmidt

It might be your best bet to get this thing running on both platforms....
0
 
LVL 1

Author Comment

by:meessen
ID: 1408911
I know ACE but I don't have time and the experience to use this package.

I now have a input thread imlementing the select operation for new connection and incomming data on sockets. I use event to signal incomming data.

I have a main thread using WaitFor... and it works fine. Well nearly fine.

The problem left is that when I start the process using pipes to redirect I/O I check the child process output pipe if it is signaled. Apparently it is but When I try to ReadFile on it the call blocks. And of course everything blocks since I never go back to the WaitFor and give other task a chance  to be executed.

Any clue on what could make this ReadFile block ?

I have a buffer of size BUFSIZE.
I do ReadFile( proc->stdout, buffer, BUFSIZE, &len, NULL );


If I manualy kill the child process, the pipe is released, and the read is terminated.
I know the process is sending an output line.

What I don't understand is why the output pipe handle is signaled and a ReadFIle will block !


0
 
LVL 1

Author Comment

by:meessen
ID: 1408912
Even worse....

I have written a small dummy program doing the following:
int main( int argc, char* argv[] ){
      HANDLE so;
      long len;
      char msg[] = "+ Hello\n";

      for( ;; ){
            int i;
            printf("- hello\r\n");

            so = GetStdHandle(STD_OUTPUT_HANDLE);
            WriteFile( so, msg, strlen(msg), &len, NULL );
            for( i = 1; i < 50000; i++ )
                  i = (i*2)/2;
      }
      return 0;
}

When run from the console I get
+ Hello
- hello
+ Hello
- hello
+ Hello
- hello
+ Hello
- hello
+ Hello
- hello
as expected.

Now run as a child process and doing a synchronous ReadFile on the stdout handle I get
A big bunch of + Hello and suddently a big bunch of - hello.
I didn't check but I guess the number of output lines is the same.
Very usefull feature.

We are now going to evaluate Linux and solaris on Intel for our 3.5 Million Dollar project.





0
 
LVL 2

Expert Comment

by:abesoft
ID: 1408913
Problem one: ReadFile doesn't return until the piped task terminates.
This is a direct result of what ReadFile is doing: Reading data until EOF.  You don't get an EOF on stdin until the process that is piping to you terminates, or the buffer is exceeded.  What I think you want to do is to read in data in smaller chunks (a byte at a time, maybe?) and process it as you see it.  You might also want to consider overlapped I/O, so you can properly handle time-outs on the input....

Problem two: Unsynchronized I/O
I think you need to flush stdin/stdout to get the two streams synchronized.  Try this:
int main( int argc, char* argv[] ){
    HANDLE so;
    long len;
    char msg[] = "+ Hello\n";

    for( ;; ){
        int i;
        printf("- hello\r\n");
        fflush( stdout);

        so = GetStdHandle(STD_OUTPUT_HANDLE);
        WriteFile( so, msg, strlen(msg), &len, NULL );
        FlushFileBuffers( so);
        for( i = 1; i < 50000; i++ )
            i = (i*2)/2;
    }
    return 0;
}


0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article shows how to make a Windows 7 gadget that extends its U/I with a flyout panel -- a window that pops out next to the gadget.  The example gadget shows several additional techniques:  How to automatically resize a gadget or flyout panel t…
zlib is a free compression library (a DLL) on which the popular gzip utility is built.  In this article, we'll see how to use the zlib functions to compress and decompress data in memory; that is, without needing to use a temporary file.  We'll be c…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question