summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qiodevice.cpp4
-rw-r--r--src/corelib/io/qiodevice_p.h7
-rw-r--r--src/corelib/io/qwindowspipewriter.cpp29
-rw-r--r--src/corelib/io/qwindowspipewriter_p.h5
-rw-r--r--src/network/socket/qlocalsocket_p.h1
-rw-r--r--src/network/socket/qlocalsocket_win.cpp41
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))