PDA

View Full Version : select() - Why doesn't it work?


tk03
05-06-2003, 10:42 PM
I'm trying to use select() to suspend my program until data is available on the descriptors in a list. But for some reason select just doesn't work. The only time my program is allowed to run is after the timeout but not when data is available. The primary descriptor I'm using it with is the descriptor returned by ConnectionNumber() in Xlib so that my program can have a GUI and work with sockets in the same process/thread.
The code I use is this:
myList.push_back(ConnectionNumber (dpy));
int highestFD = myList[0];

while (1)
{
tv.tv_usec = 0;
tv.tv_sec = 1;
FD_ZERO(&fd);
for(unsigned int i = 0;i<myList.size();++i)
{
FD_SET(myList[i], &fd);
if(myList[i] > highestFD)
highestFD = myList[i];
}

select (highestFD+1, &fd, 0, 0, &tv);
//prints data to shell to see that it worked.
}

Am I misusing this function or is this a bug in the system libraries? Note, the OS I'm using is Gentoo Linux(Arch: x86).

RobSeace
05-06-2003, 11:09 PM
Well, I'm no X-Windows programming wiz (I used to absolutely
loathe what little of it I experienced ;-)), but are you sure that
ConnectionNumber() is really returning a valid file descriptor??
If so, are you sure it's actually readable, when select() says it's
not?

tk03
05-07-2003, 04:38 AM
If it's not a vaild fd then there's a serious bug in Xlib(Not that it would be a huge suprise).
This shows that it is meant to return a vaild fd.
#define ConnectionNumber(dpy) (((_XPrivDisplay)dpy)->fd)
If it's not readable then why would there be a macro for clients using Xlib to obtain the descripter? Using ConnectionNumber() with select() as far as I know is common. I've seen that blackbox uses it with select. I've even used it once in another programmer to create a timer that also allowed the program to get X events.

zapdog
05-07-2003, 02:43 PM
Here is part of a post by Tim Love that explains the issue:

For various reasons (including network efficiency, I suppose) some X events which are yet to be seen are stored in a queue in main memory. Hence, even though there may be nothing to read on ConnectionNumber(display), there might be X events held locally by the Xlib data structures. So make sure to use XPending(display) before doing a blocking select call. Otherwise your program is likely to hang.

The chapter on event processing in "Introduction to the X Window System", by Oliver Jones, Prentice-Hall, 1988 (ISBN 0-13-499997-5) also discusses this.

tk03
05-07-2003, 10:24 PM
Thanks zapdog! That seems to have been the problem.
I'm going to start trying to get network sockets working in my program to see if it will work for both X11 and network sockets.