[Qt-interest] Why Bus error clientSocket->waitForConnected()?
Kustaa Nyholm
Kustaa.Nyholm at planmeca.com
Mon May 3 10:17:19 CEST 2010
> No, that was a good design. All of the API is non-blocking and that's a good
> design.
Why? Who needs a non blocking readline? Like I've already said several times
I would love to see a use case where this is needed...
>
>> or a bad decision to call it readline when many other APIs/libraries and
>> common user expectation is that readline will block.
>
> Maybe the bad decision was to return anything if full a line can't be read but
> the device isn't at the end yet.
So you are conceding that it should block or that it was a bad piece of API
desing...... ;-)
>
> Unfortunately, by the time we made QIODevice properly understand "can't read
> because it's EOF" and "can't read because there is no more data but the
> socket/process can still receive more", the readLine behaviour was set.
So it was not a perfect design decision?
>
> Sometimes devices and files end without a newline. So readLine() returns an
> unfinished line if EOF is found first.
As most people would expect, I guess.
However,the documentation for QSocket::readLine says:
Returns "" if canReadLine() returns FALSE.
So it does not return the last line at all if it is not new line terminated?
> As I said before, if you want to block, you have to call a "waitFor" function.
> There's none above, so it doesn't block. it simply busy-loops forever.
You insist on telling me how to use API, I don't need that information, I
know how to use it. My sole point was that the API design could have been
better, alas too late to fix that now.
>> So I think Qt has got this small detail wrong.
>
> Or you did.
>
That is totally possible, but obviously I do not agree, but you don't get Qt
folks to admit an error often, even the tiniest...
> canReadLine() will return true for as long as there's a line to be read. If
> the device, process or socket is closed without a newline at the end,
> canReadLine() will return false for that last chunk of data. But readLine()
> will return it.
According to the documentation this is not so, but regardless, how
is this API proposed to be used?
With Java API design I would do something like:
while (null != (line = reader.readLine()))
processLine( line );
How about Qt? I've not compiled nor tested following, so I'm working
from the documentation acting as a novice:
First I have several issues with the waitForMore documentation, which
says:
If msecs is -1 the call will block indefinitely.
I presume this means block until data is available, but what about
if there is an error? What about if there is eof / socket closed?
The documentation says: "...no error occurred (i.e. it does not return
-1)"
so I presume that in case of error waitForMore will return with -1.
Ok, but is eof/closed socket and error?
The documentation then says:
"...it sets *timeout to FALSE. This is useful to find out if the
peer closed the connection."
What is this trying to say? Let me try to decipher that:
it implies that the function can return before a timeout is reached
even if no data is available. The previous sentence implied that an error is
indicated by return value of -1 and so the above implies the function
will return in case of error or eof, and that *timeout==FALSE and return
value==0 is an indication of eof?
So I presume this is the way to handle eod/closed socket situation.
My first stab at the code would thus be
while (socket.waitForMore(-1) > 0) {
if (socket.canReadLine())
processLine(sockect.readLine());
}
processLine(sockect.readLine()); // catch the last line
This does not handle errors but neither does my Java example (don't want
to start discussing exceptions versus error codes). However if the
loop is terminated because of an error the second processLine will be
called with "" argument whereas logically it should not be called at all,
so I should add mode code separte the eof from the error case.
In view of the documentation it seems doubtful if this will process the last
line if it is not newline terminated. In which case the last code line
is superfluous, but how do we then process the last line?
The code also begs the question how waitForMore is implemented internally,
ie what happens when some bytes are available but canReadLine returns false
and thus readLine will not be called to consume them?
The main ugliness here is that processLine appears twice which is
a bad practice and almost dictates that it needs to be a subroutine so
that we catch, what ever processing it presents here, in only one place, or
like I said above, how do we process that last line?
But I have very little practical Qt experience yet, so maybe some one
shows how this is supposed to done in Qt?
br Kusti
More information about the Qt-interest-old
mailing list