diff options
author | Joerg Bornemann <joerg.bornemann@nokia.com> | 2009-09-03 16:03:16 (GMT) |
---|---|---|
committer | Joerg Bornemann <joerg.bornemann@nokia.com> | 2009-09-04 09:21:00 (GMT) |
commit | 3035e9cd81dcadb23d77c69d4b1e96ec1550d67c (patch) | |
tree | 8b52a22c110be89911212cfb086d62c3316db991 /src | |
parent | 9564ee48e588c602057ee458acfe881385681cf3 (diff) | |
download | Qt-3035e9cd81dcadb23d77c69d4b1e96ec1550d67c.zip Qt-3035e9cd81dcadb23d77c69d4b1e96ec1550d67c.tar.gz Qt-3035e9cd81dcadb23d77c69d4b1e96ec1550d67c.tar.bz2 |
fix disconnect-after-write-problem in QLocalSocket on Windows
If the server disconnects directly after writing its data, like the
localfortuneserver example does, we must close the reading client
socket. Before this patch, an error was yielded.
Task-number: 260631
Reviewed-by: phartman
Diffstat (limited to 'src')
-rw-r--r-- | src/network/socket/qlocalsocket_p.h | 2 | ||||
-rw-r--r-- | src/network/socket/qlocalsocket_win.cpp | 43 |
2 files changed, 34 insertions, 11 deletions
diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index a774cbf..a7248f6 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -139,7 +139,7 @@ public: void _q_emitReadyRead(); DWORD bytesAvailable(); void startAsyncRead(); - void completeAsyncRead(); + bool completeAsyncRead(); void checkReadyRead(); HANDLE handle; OVERLAPPED overlapped; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index f70a0aa..96dfa6e 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -199,9 +199,13 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) } } - if (!d->readSequenceStarted) - d->startAsyncRead(); - d->checkReadyRead(); + if (d->pipeClosed) { + QTimer::singleShot(0, this, SLOT(_q_pipeClosed())); + } else { + if (!d->readSequenceStarted) + d->startAsyncRead(); + d->checkReadyRead(); + } return readSoFar; } @@ -251,9 +255,22 @@ void QLocalSocketPrivate::startAsyncRead() readSequenceStarted = true; if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) { completeAsyncRead(); - } else if (GetLastError() != ERROR_IO_PENDING) { - setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead")); - return; + } else { + switch (GetLastError()) { + case ERROR_IO_PENDING: + // This is not an error. We're getting notified, when data arrives. + return; + case ERROR_PIPE_NOT_CONNECTED: + { + // It may happen, that the other side closes the connection directly + // after writing data. Then we must set the appropriate socket state. + pipeClosed = true; + return; + } + default: + setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead")); + return; + } } } while (!readSequenceStarted); } @@ -261,20 +278,23 @@ void QLocalSocketPrivate::startAsyncRead() /*! \internal Sets the correct size of the read buffer after a read operation. + Returns false, if an error occured or the connection dropped. */ -void QLocalSocketPrivate::completeAsyncRead() +bool QLocalSocketPrivate::completeAsyncRead() { ResetEvent(overlapped.hEvent); readSequenceStarted = false; DWORD bytesRead; if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) { - setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); - return; + if (GetLastError() != ERROR_PIPE_NOT_CONNECTED) + setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead")); + return false; } actualReadBufferSize += bytesRead; readBuffer.truncate(actualReadBufferSize); + return true; } qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) @@ -425,7 +445,10 @@ void QLocalSocketPrivate::_q_canWrite() void QLocalSocketPrivate::_q_notified() { Q_Q(QLocalSocket); - completeAsyncRead(); + if (!completeAsyncRead()) { + pipeClosed = true; + return; + } startAsyncRead(); pendingReadyRead = false; emit q->readyRead(); |