Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
4.6.3, 4.7.0, 4.7.1, 4.8.x, 5.0.0, Some future release
-
None
-
0bf8f70f85a24ab2864775bdd38f5ced43a7d4de
Description
void QLocalSocketPrivate::setErrorString(const QString &function) { .... switch (windowsError) { case ERROR_PIPE_NOT_CONNECTED: case ERROR_BROKEN_PIPE: case ERROR_NO_DATA: error = QLocalSocket::ConnectionError; errorString = QLocalSocket::tr("%1: Connection error").arg(function); state = QLocalSocket::UnconnectedState; break; ...
bool QLocalSocketPrivate::completeAsyncRead() { ... if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { if (GetLastError() != ERROR_PIPE_NOT_CONNECTED) setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); return false; } ... }
If GetOverlappedResult() return ERROR_BROKEN_PIPE or ERROR_NO_DATA, error will be emitted.
My code use one call to readAll() inside slot connected with readyRead() signal.
And in my case, data successfully read from pipe, but after readyRead signal, error signal emitted. I think, that thiese signal emitted simultaneously, but slots in my case called in such order.
This happen when remote application use namedpipe with ::CallNamedPipe() winapi function. In such case, pipe opened, written and read very quickly (uninterruptible inside kernel?) in my case, clients does not read anything, just open and write.
I can easy reproduce bug.
Fix of bool QLocalSocketPrivate::completeAsyncRead()
DWORD err=GetLastError(); switch(err) { case ERROR_PIPE_NOT_CONNECTED: case ERROR_BROKEN_PIPE: /* not sure */ case ERROR_NO_DATA: /* nothing read */ break; default: setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); } return false;