summaryrefslogtreecommitdiffstats
path: root/src/network/socket
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/socket')
-rw-r--r--src/network/socket/qlocalserver_p.h1
-rw-r--r--src/network/socket/qlocalserver_win.cpp6
-rw-r--r--src/network/socket/qlocalsocket_p.h2
-rw-r--r--src/network/socket/qlocalsocket_win.cpp25
4 files changed, 23 insertions, 11 deletions
diff --git a/src/network/socket/qlocalserver_p.h b/src/network/socket/qlocalserver_p.h
index feaaae0..4f92b64 100644
--- a/src/network/socket/qlocalserver_p.h
+++ b/src/network/socket/qlocalserver_p.h
@@ -99,6 +99,7 @@ public:
struct Listener {
HANDLE handle;
OVERLAPPED overlapped;
+ bool connected;
};
void setError(const QString &function);
diff --git a/src/network/socket/qlocalserver_win.cpp b/src/network/socket/qlocalserver_win.cpp
index 07baf1e..61220e4 100644
--- a/src/network/socket/qlocalserver_win.cpp
+++ b/src/network/socket/qlocalserver_win.cpp
@@ -85,8 +85,10 @@ bool QLocalServerPrivate::addListener()
if (!ConnectNamedPipe(listener.handle, &listener.overlapped)) {
switch (GetLastError()) {
case ERROR_IO_PENDING:
+ listener.connected = false;
break;
case ERROR_PIPE_CONNECTED:
+ listener.connected = true;
SetEvent(eventHandle);
break;
default:
@@ -155,7 +157,9 @@ void QLocalServerPrivate::_q_onNewConnection()
// a client connection first, so there is no way around polling all of them.
for (int i = 0; i < listeners.size(); ) {
HANDLE handle = listeners[i].handle;
- if (GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE)) {
+ if (listeners[i].connected
+ || GetOverlappedResult(handle, &listeners[i].overlapped, &dummy, FALSE))
+ {
listeners.removeAt(i);
addListener();
diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h
index 0f1c23c..57ca3c2 100644
--- a/src/network/socket/qlocalsocket_p.h
+++ b/src/network/socket/qlocalsocket_p.h
@@ -135,7 +135,7 @@ public:
void _q_canWrite();
void _q_pipeClosed();
void _q_emitReadyRead();
- DWORD bytesAvailable();
+ DWORD checkPipeState();
void startAsyncRead();
bool completeAsyncRead();
void checkReadyRead();
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 5f46ecb..2223ebe 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -192,6 +192,9 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
{
Q_D(QLocalSocket);
+ if (d->pipeClosed && d->actualReadBufferSize == 0)
+ return -1; // signal EOF
+
qint64 readSoFar;
// If startAsyncRead() read data, copy it to its destination.
if (maxSize == 1 && d->actualReadBufferSize > 0) {
@@ -213,10 +216,8 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
}
if (d->pipeClosed) {
- if (readSoFar == 0) {
+ if (d->actualReadBufferSize == 0)
QTimer::singleShot(0, this, SLOT(_q_pipeClosed()));
- return -1; // signal EOF
- }
} else {
if (!d->readSequenceStarted)
d->startAsyncRead();
@@ -250,7 +251,10 @@ void QLocalSocketPrivate::checkReadyRead()
void QLocalSocketPrivate::startAsyncRead()
{
do {
- DWORD bytesToRead = bytesAvailable();
+ DWORD bytesToRead = checkPipeState();
+ if (pipeClosed)
+ return;
+
if (bytesToRead == 0) {
// There are no bytes in the pipe but we need to
// start the overlapped read with some buffer size.
@@ -333,9 +337,11 @@ void QLocalSocket::abort()
}
/*!
- The number of bytes available from the pipe
- */
-DWORD QLocalSocketPrivate::bytesAvailable()
+ \internal
+ Returns the number of available bytes in the pipe.
+ Sets QLocalSocketPrivate::pipeClosed to true if the connection is broken.
+ */
+DWORD QLocalSocketPrivate::checkPipeState()
{
Q_Q(QLocalSocket);
DWORD bytes;
@@ -345,7 +351,8 @@ DWORD QLocalSocketPrivate::bytesAvailable()
if (!pipeClosed) {
pipeClosed = true;
emit q->readChannelFinished();
- QTimer::singleShot(0, q, SLOT(_q_pipeClosed()));
+ if (actualReadBufferSize == 0)
+ QTimer::singleShot(0, q, SLOT(_q_pipeClosed()));
}
}
return 0;
@@ -529,7 +536,7 @@ bool QLocalSocket::waitForDisconnected(int msecs)
}
QIncrementalSleepTimer timer(msecs);
forever {
- d->bytesAvailable(); // to check if PeekNamedPipe fails
+ d->checkPipeState();
if (d->pipeClosed)
close();
if (state() == UnconnectedState)