PDA

View Full Version : Blocking API problem for TCP sockets, maybe other IO devices



spraff
11th April 2010, 11:44
Hello, all.

I've been putting together a little protocol that uses QDataStreams and QIODevices. I am expecting to use it on QTcpSockets but I want to keep things at the QIODevice level.

At the recieve end I was doing the following:

if (false == d_stream.device()->waitForReadyRead(-1)) {
// Report error.
}
while (d_stream.device()->bytesAvailable() < sizeof(Header)) {
// Spin. This shouldn't take long, the header is small, so
// once any data is available, it probably all will be.
}

This would block on waitForReadyRead if all the data had already arrived, which was surprising.

I have changed this now to

/* (1) */while (d_stream.device()->bytesAvailable() < sizeof(Header)) {
/* (2) */ if (false == d_stream.device()->waitForReadyRead(-1)) {
// Report error
}
}

This seems to work, and at a glance it makes a certain sense, but isn't there now a race condition? If all the data arrives between (1) and (2) then (2) will block as it did in my first implementation.

This code is supposed to be in a high-reliability, high-frequency application. "Unlikely" isn't good enough.

Am I using the API wrong or is this a hole in Qt?

Thanks for reading.