Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

select and WaitForMultipleObjects

Posted on 1998-06-29
10
Medium Priority
?
2,423 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 3
10 Comments
 
LVL 2

Accepted Solution

by:
abesoft earned 100 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
Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

 
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

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

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 accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
This article describes how to add a user-defined command button to the Windows 7 Explorer toolbar.  In the previous article (http://www.experts-exchange.com/A_2172.html), we saw how to put the Delete button back there where it belongs.  "Delete" is …
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 course is ideal for IT System Administrators working with VMware vSphere and its associated products in their company infrastructure. This course teaches you how to install and maintain this virtualization technology to store data, prevent vuln…

618 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