diff options
author | Joerg Bornemann <joerg.bornemann@theqtcompany.com> | 2016-03-23 15:45:12 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com> | 2016-03-24 16:12:46 +0000 |
commit | 24411e9743735d6323f1d3686f8b989a5122f83b (patch) | |
tree | 67323f338eb7b189dfce88aa1419cf63cd96ef4e /src/network/socket/qlocalsocket_win.cpp | |
parent | f75d950bd4353c436f9863d06af65b6cbc672c76 (diff) |
Add a write buffer to QLocalSocket/Win
Commit 0307c008 removed the buffering of data-to-be-written from
QWindowsPipeWriter, because it was assumed that users of this class
(QProcess and QLocalSocket) already buffer data internally.
This assumption was wrong for QLocalSocket. The following sequence
localSocket->write(someData);
localSocket->write(someMoreData);
would not write anything on the second write.
Add a write buffer to the Windows implementation of QLocalSocket.
Task-number: QTBUG-52073
Change-Id: I6d0f03a722ec48138cbde3e2f69aae7dafe790d3
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'src/network/socket/qlocalsocket_win.cpp')
-rw-r--r-- | src/network/socket/qlocalsocket_win.cpp | 48 |
1 files changed, 36 insertions, 12 deletions
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 03ad2b6654..d477de9c47 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -207,15 +207,21 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize) } } -qint64 QLocalSocket::writeData(const char *data, qint64 maxSize) +qint64 QLocalSocket::writeData(const char *data, qint64 len) { Q_D(QLocalSocket); + if (len == 0) + return 0; + char *dest = d->writeBuffer.reserve(len); + memcpy(dest, data, len); if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); - connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite())); - connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64))); + QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, + d, &QLocalSocketPrivate::_q_bytesWritten); } - return d->pipeWriter->write(data, maxSize); + if (!d->pipeWriter->isWriteOperationActive()) + d->startNextWrite(); + return len; } void QLocalSocket::abort() @@ -224,6 +230,7 @@ void QLocalSocket::abort() if (d->pipeWriter) { delete d->pipeWriter; d->pipeWriter = 0; + d->writeBuffer.clear(); } close(); } @@ -266,7 +273,7 @@ qint64 QLocalSocket::bytesAvailable() const qint64 QLocalSocket::bytesToWrite() const { Q_D(const QLocalSocket); - return (d->pipeWriter) ? d->pipeWriter->bytesToWrite() : 0; + return d->writeBuffer.size(); } bool QLocalSocket::canReadLine() const @@ -298,9 +305,12 @@ void QLocalSocket::close() bool QLocalSocket::flush() { Q_D(QLocalSocket); - if (d->pipeWriter) - return d->pipeWriter->waitForWrite(0); - return false; + bool written = false; + if (d->pipeWriter) { + while (d->pipeWriter->waitForWrite(0)) + written = true; + } + return written; } void QLocalSocket::disconnectFromServer() @@ -313,10 +323,11 @@ void QLocalSocket::disconnectFromServer() // It must be destroyed before close() to prevent an infinite loop. delete d->pipeWriter; d->pipeWriter = 0; + d->writeBuffer.clear(); } flush(); - if (d->pipeWriter && d->pipeWriter->bytesToWrite() != 0) { + if (bytesToWrite() != 0) { d->state = QLocalSocket::ClosingState; emit stateChanged(d->state); } else { @@ -345,11 +356,24 @@ bool QLocalSocket::setSocketDescriptor(qintptr socketDescriptor, return true; } -void QLocalSocketPrivate::_q_canWrite() +void QLocalSocketPrivate::startNextWrite() +{ + Q_Q(QLocalSocket); + if (writeBuffer.isEmpty()) { + if (state == QLocalSocket::ClosingState) + q->close(); + } else { + Q_ASSERT(pipeWriter); + pipeWriter->write(writeBuffer.readPointer(), writeBuffer.nextDataBlockSize()); + } +} + +void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes) { Q_Q(QLocalSocket); - if (state == QLocalSocket::ClosingState) - q->close(); + writeBuffer.free(bytes); + startNextWrite(); + emit q->bytesWritten(bytes); } qintptr QLocalSocket::socketDescriptor() const |