diff options
-rw-r--r-- | src/corelib/io/qiodevice.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qiodevice_p.h | 7 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter.cpp | 29 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter_p.h | 5 | ||||
-rw-r--r-- | src/network/socket/qlocalsocket_p.h | 1 | ||||
-rw-r--r-- | src/network/socket/qlocalsocket_win.cpp | 41 |
6 files changed, 47 insertions, 40 deletions
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index f3354cad65..3e3ee6e406 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -1763,9 +1763,7 @@ qint64 QIODevice::write(const QByteArray &data) */ void QIODevicePrivate::write(const char *data, qint64 size) { - if (currentWriteChunk != nullptr - && currentWriteChunk->constData() == data - && currentWriteChunk->size() == size) { + if (isWriteChunkCached(data, size)) { // We are called from write(const QByteArray &) overload. // So, we can make a shallow copy of chunk. writeBuffer.append(*currentWriteChunk); diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h index 3f8e459d88..3639418bbc 100644 --- a/src/corelib/io/qiodevice_p.h +++ b/src/corelib/io/qiodevice_p.h @@ -185,6 +185,13 @@ public: qint64 skipByReading(qint64 maxSize); void write(const char *data, qint64 size); + inline bool isWriteChunkCached(const char *data, qint64 size) const + { + return currentWriteChunk != nullptr + && currentWriteChunk->constData() == data + && currentWriteChunk->size() == size; + } + #ifdef QT_NO_QOBJECT QIODevice *q_ptr = nullptr; #endif diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index f2f4dce056..cfa486451c 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -121,16 +121,35 @@ qint64 QWindowsPipeWriter::bytesToWrite() const } /*! - Writes data to the pipe. + Writes a shallow copy of \a ba to the internal buffer. */ bool QWindowsPipeWriter::write(const QByteArray &ba) { + return writeImpl(ba); +} + +/*! + Writes data to the internal buffer. + */ +bool QWindowsPipeWriter::write(const char *data, qint64 size) +{ + return writeImpl(data, size); +} + +template <typename... Args> +inline bool QWindowsPipeWriter::writeImpl(Args... args) +{ QMutexLocker locker(&mutex); if (lastError != ERROR_SUCCESS) return false; - writeBuffer.append(ba); + writeBuffer.append(args...); + return writeImplTail(&locker); +} + +bool QWindowsPipeWriter::writeImplTail(QMutexLocker<QMutex> *locker) +{ if (writeSequenceStarted) return true; @@ -143,10 +162,10 @@ bool QWindowsPipeWriter::write(const QByteArray &ba) if (!winEventActPosted) { winEventActPosted = true; - locker.unlock(); + locker->unlock(); QCoreApplication::postEvent(this, new QEvent(QEvent::WinEventAct)); } else { - locker.unlock(); + locker->unlock(); } SetEvent(syncHandle); @@ -232,8 +251,6 @@ void QWindowsPipeWriter::waitCallback(PTP_CALLBACK_INSTANCE instance, PVOID cont bool QWindowsPipeWriter::writeCompleted(DWORD errorCode, DWORD numberOfBytesWritten) { if (errorCode == ERROR_SUCCESS) { - Q_ASSERT(numberOfBytesWritten == DWORD(writeBuffer.nextDataBlockSize())); - bytesWrittenPending = true; pendingBytesWrittenValue += numberOfBytesWritten; writeBuffer.free(numberOfBytesWritten); diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index cb78195a85..f8cabb225d 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -69,6 +69,7 @@ public: ~QWindowsPipeWriter(); bool write(const QByteArray &ba); + bool write(const char *data, qint64 size); void stop(); bool waitForWrite(int msecs); bool checkForWrite() { return consumePendingAndEmit(false); } @@ -83,6 +84,10 @@ protected: bool event(QEvent *e) override; private: + template <typename... Args> + inline bool writeImpl(Args... args); + bool writeImplTail(QMutexLocker<QMutex> *locker); + void startAsyncWriteLocked(); static void CALLBACK waitCallback(PTP_CALLBACK_INSTANCE instance, PVOID context, PTP_WAIT wait, TP_WAIT_RESULT waitResult); diff --git a/src/network/socket/qlocalsocket_p.h b/src/network/socket/qlocalsocket_p.h index d5169e1296..8dd71ece54 100644 --- a/src/network/socket/qlocalsocket_p.h +++ b/src/network/socket/qlocalsocket_p.h @@ -136,7 +136,6 @@ public: qint64 pipeWriterBytesToWrite() const; void _q_canRead(); void _q_bytesWritten(qint64 bytes); - void writeToSocket(); void _q_pipeClosed(); void _q_winError(ulong windowsError, const QString &function); HANDLE handle; diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp index 02e2b5d0a3..912ebf412c 100644 --- a/src/network/socket/qlocalsocket_win.cpp +++ b/src/network/socket/qlocalsocket_win.cpp @@ -157,7 +157,6 @@ QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(), emittedReadyRead(false), emittedBytesWritten(false) { - writeBufferChunkSize = QIODEVICE_BUFFERSIZE; } QLocalSocketPrivate::~QLocalSocketPrivate() @@ -276,13 +275,18 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len) if (len == 0) return 0; - d->write(data, len); + if (!d->pipeWriter) { d->pipeWriter = new QWindowsPipeWriter(d->handle, this); QObjectPrivate::connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten, d, &QLocalSocketPrivate::_q_bytesWritten); } - d->writeToSocket(); + + if (d->isWriteChunkCached(data, len)) + d->pipeWriter->write(*(d->currentWriteChunk)); + else + d->pipeWriter->write(data, len); + return len; } @@ -340,7 +344,7 @@ qint64 QLocalSocket::bytesAvailable() const qint64 QLocalSocket::bytesToWrite() const { Q_D(const QLocalSocket); - return d->writeBuffer.size() + d->pipeWriterBytesToWrite(); + return d->pipeWriterBytesToWrite(); } bool QLocalSocket::canReadLine() const @@ -389,7 +393,6 @@ void QLocalSocket::disconnectFromServer() // It must be destroyed before close() to prevent an infinite loop. delete d->pipeWriter; d->pipeWriter = 0; - d->writeBuffer.clear(); } flush(); @@ -434,21 +437,8 @@ void QLocalSocketPrivate::_q_bytesWritten(qint64 bytes) QScopedValueRollback<bool> guard(emittedBytesWritten, true); emit q->bytesWritten(bytes); } - if (writeBuffer.isEmpty()) { - if (state == QLocalSocket::ClosingState && pipeWriterBytesToWrite() == 0) - q->close(); - } else { - writeToSocket(); - } -} - -void QLocalSocketPrivate::writeToSocket() -{ - Q_ASSERT(pipeWriter); - Q_ASSERT(!writeBuffer.isEmpty()); - - if (!pipeWriter->isWriteOperationActive()) - pipeWriter->write(writeBuffer.read()); + if (state == QLocalSocket::ClosingState && pipeWriterBytesToWrite() == 0) + q->close(); } qintptr QLocalSocket::socketDescriptor() const @@ -489,9 +479,6 @@ bool QLocalSocket::waitForDisconnected(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - if (!d->writeBuffer.isEmpty()) - d->writeToSocket(); - QSocketPoller poller(*d); if (!poller.poll(deadline)) return false; @@ -525,9 +512,6 @@ bool QLocalSocket::waitForReadyRead(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - if (!d->writeBuffer.isEmpty()) - d->writeToSocket(); - QSocketPoller poller(*d); if (poller.waitForClose || !poller.poll(deadline)) return false; @@ -551,11 +535,8 @@ bool QLocalSocket::waitForBytesWritten(int msecs) QDeadlineTimer deadline(msecs); while (!d->pipeReader->isPipeClosed()) { - if (!d->writeBuffer.isEmpty()) { - d->writeToSocket(); - } else if (d->pipeWriterBytesToWrite() == 0) { + if (bytesToWrite() == 0) return false; - } QSocketPoller poller(*d); if (!poller.poll(deadline)) |