summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@nokia.com>2009-09-03 16:03:16 (GMT)
committerJoerg Bornemann <joerg.bornemann@nokia.com>2009-09-04 09:21:00 (GMT)
commit3035e9cd81dcadb23d77c69d4b1e96ec1550d67c (patch)
tree8b52a22c110be89911212cfb086d62c3316db991 /src
parent9564ee48e588c602057ee458acfe881385681cf3 (diff)
downloadQt-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.h2
-rw-r--r--src/network/socket/qlocalsocket_win.cpp43
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();