PDA

View Full Version : Resize caught by select()



mhoover
17th July 2009, 01:37
For some reason if I start a select() statement while I'm resizing my QMainWindow, the select() returns instantly and my recvfrom command hangs.

Is there anyway a resizeEvent would put info on a port somehow?

I'm wondering if there is a way to check if the window is getting resized, but this seems like a kludge because I'm not sure what other events would do this as well.

Here is my select function that calls itself every check_interval:



void MyClient::checkForData() {
logEvent( "About to check for data.", 2 );
char rbuffer[1024];
struct sockaddr_in from;
size_t fromlen = sizeof( from );

// set up variables to make the select call
struct timeval tv;
tv.tv_sec = wait_time_seconds; // how long to wait
tv.tv_usec = wait_time_microseconds;
fd_set read_fds;
FD_SET( sock, &read_fds );
logEvent( "Checking for data.", 1 );

int num_responses = 0;
if ( num_responses = select( sock+1, &read_fds, NULL, NULL, &tv ) > 0 ) {
logEvent( QString( "Received data on %1 sockets." ).arg( num_responses ), 2 );
recvfrom( sock, &rbuffer, sizeof( rbuffer ), 0, (struct sockaddr *) &from, &fromlen );
QString the_response( rbuffer );
logEvent( "The response: '" + the_response + "'", 4 );
emit responseReady( the_response );
} else {
logEvent( "No response.", 4 );
}

QTimer::singleShot( check_interval, this, SLOT( checkForData() ) );
}

If I resize it when the code checks the socket with the select call I only see:


About to check for data.
Checking for data.
Received data on 1 sockets.

And then it freezes.

nish
17th July 2009, 01:57
i think the timer is giving you a infinite recursion, BTW why dont you use QTcpSocket?

mhoover
17th July 2009, 03:16
Interesting. It would definitely be a bug in the timer because it works fine at 1 Hz as long as I don't resize the window.

I'm not using QUdpSocket because I had this issue:

http://www.qtcentre.org/forum/f-qt-programming-2/t-qudpsocket-not-getting-responses-22299.html/?highlight=QUdpSocket

Which is basically that I could read and write everything I wanted to using QUdpSocket except the case where I was getting a response from a Scheme server. (I could get scheme messages, but not if they were in response to something, and I got responses fine from a Qt based server).

mhoover
17th July 2009, 04:04
Ah ... It turns out Unix is often doing things with descriptors when you have GUI events and this can get picked up by a select() function even when the fd you pass to select() has not had any activity.

My solution (workaround?) for now is to pass a MSG_DONTWAIT to the recvfrom function. This can return garbage, so you have to check the number of bytes.




if ( recvfrom( sock, &rbuffer, sizeof( rbuffer ), MSG_DONTWAIT, (struct sockaddr *) &from, &fromlen ) > 0 ) {
...


Another thing would be to check if an EAGAIN error was returned, but I don't know how to do that.

I'm surprised I couldn't call something to see if there's something waiting on the socket with out blocking/waiting. In Qt land there's something like that (readyForRead() or something), but I guess there's no equivalent for berkeley sockets.