Solved

select and WaitForMultipleObjects

Posted on 1998-06-29
10
2,275 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
 
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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
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…
This video discusses moving either the default database or any database to a new volume.

757 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now