diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2021-05-12 19:25:15 +0300 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@gmx.de> | 2021-05-18 20:03:47 +0000 |
commit | 9c7cabb880954d97d68cdbf34abc567a7494c922 (patch) | |
tree | 1af4073ec47393211b6522c5e33339e9cf4316eb /src/network/socket/qlocalsocket_win.cpp | |
parent | 91c65dd80cdd2de666448c14202c0c63718152b6 (diff) |
QLocalSocket/Win: fix closed state detection in waitFor...() functions
A delayed close should only be completed in the _q_bytesWritten() slot
as a confirmation of a successful write operation on the socket.
Otherwise, a failed write operation may cause the socket to be closed
unexpectedly within the waitFor...() function, which may result in a
malfunction.
Change-Id: I14cff26734f64a89090b6b5c13037466a6400597
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/network/socket/qlocalsocket_win.cpp')
-rw-r--r-- | src/network/socket/qlocalsocket_win.cpp | 35 |
1 files changed, 20 insertions, 15 deletions
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 37ca09e5d3..02e2b5d0a3 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -282,7 +282,7 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, d, &QLocalSocketPrivate::_q_bytesWritten); } - d->_q_canWrite(); + d->writeToSocket(); return len; } @@ -434,22 +434,23 @@ void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes) QScopedValueRollback<bool> guard(emittedBytesWritten, true); emit q->bytesWritten(bytes); } - _q_canWrite(); -} - -void QLocalSocketPrivate::_q_canWrite() -{ - Q_Q(QLocalSocket); if (writeBuffer.isEmpty()) { if (state == QLocalSocket::ClosingState && pipeWriterBytesToWrite() == 0) q->close(); } else { - Q_ASSERT(pipeWriter); - if (!pipeWriter->isWriteOperationActive()) - pipeWriter->write(writeBuffer.read()); + writeToSocket(); } } +void QLocalSocketPrivate::writeToSocket() +{ + Q_ASSERT(pipeWriter); + Q_ASSERT(!writeBuffer.isEmpty()); + + if (!pipeWriter->isWriteOperationActive()) + pipeWriter->write(writeBuffer.read()); +} + qintptr QLocalSocket::socketDescriptor() const { Q_D(const QLocalSocket); @@ -488,7 +489,8 @@ bool QLocalSocket::waitForDisconnected(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - d->_q_canWrite(); + if (!d->writeBuffer.isEmpty()) + d->writeToSocket(); QSocketPoller poller(*d); if (!poller.poll(deadline)) @@ -499,7 +501,7 @@ bool QLocalSocket::waitForDisconnected(int msecs) // When the read buffer is full, the read sequence is not running, // so we need to peek the pipe to detect disconnection. - if (poller.waitForClose) + if (poller.waitForClose && isValid()) d->pipeReader->checkPipeState(); d->pipeReader->checkForReadyRead(); @@ -523,7 +525,8 @@ bool QLocalSocket::waitForReadyRead(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - d->_q_canWrite(); + if (!d->writeBuffer.isEmpty()) + d->writeToSocket(); QSocketPoller poller(*d); if (poller.waitForClose || !poller.poll(deadline)) @@ -548,9 +551,11 @@ bool QLocalSocket::waitForBytesWritten(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - if (bytesToWrite() == 0) + if (!d->writeBuffer.isEmpty()) { + d->writeToSocket(); + } else if (d->pipeWriterBytesToWrite() == 0) { return false; - d->_q_canWrite(); + } QSocketPoller poller(*d); if (!poller.poll(deadline)) |