summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/global/qhooks.cpp2
-rw-r--r--src/corelib/io/qiodevice.cpp32
-rw-r--r--src/corelib/io/qiodevice_p.h4
-rw-r--r--src/corelib/io/qprocess.cpp2
-rw-r--r--src/network/socket/qabstractsocket.cpp2
-rw-r--r--src/network/socket/qlocalsocket_win.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp2
-rw-r--r--tests/auto/other/toolsupport/tst_toolsupport.cpp4
8 files changed, 40 insertions, 10 deletions
diff --git a/src/corelib/global/qhooks.cpp b/src/corelib/global/qhooks.cpp
index 22f01853b7..5a0caa2ed0 100644
--- a/src/corelib/global/qhooks.cpp
+++ b/src/corelib/global/qhooks.cpp
@@ -67,7 +67,7 @@ quintptr Q_CORE_EXPORT qtHookData[] = {
// The required sizes and offsets are tested in tests/auto/other/toolsupport.
// When this fails and the change was intentional, adjust the test and
// adjust this value here.
- 18
+ 19
};
static_assert(QHooks::LastHookIndex == sizeof(qtHookData) / sizeof(qtHookData[0]));
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 3d64e8820f..b920fbb17b 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -158,13 +158,14 @@ static void checkWarnMessage(const QIODevice *device, const char *function, cons
QIODevicePrivate::QIODevicePrivate()
: openMode(QIODevice::NotOpen),
pos(0), devicePos(0),
+ transactionPos(0),
readChannelCount(0),
writeChannelCount(0),
currentReadChannel(0),
currentWriteChannel(0),
readBufferChunkSize(QIODEVICE_BUFFERSIZE),
writeBufferChunkSize(0),
- transactionPos(0),
+ currentWriteChunk(nullptr),
transactionStarted(false)
, baseReadLineDataCalled(false)
, accessMode(Unset)
@@ -1750,7 +1751,34 @@ qint64 QIODevice::write(const char *data)
qint64 QIODevice::write(const QByteArray &data)
{
- return write(data.constData(), data.size());
+ Q_D(QIODevice);
+
+ // Keep the chunk pointer for further processing in
+ // QIODevicePrivate::write(). To reduce fragmentation,
+ // the chunk size must be sufficiently large.
+ if (data.size() >= QRINGBUFFER_CHUNKSIZE)
+ d->currentWriteChunk = &data;
+
+ const qint64 ret = write(data.constData(), data.size());
+
+ d->currentWriteChunk = nullptr;
+ return ret;
+}
+
+/*!
+ \internal
+*/
+void QIODevicePrivate::write(const char *data, qint64 size)
+{
+ if (currentWriteChunk != nullptr
+ && currentWriteChunk->constData() == data
+ && currentWriteChunk->size() == size) {
+ // We are called from write(const QByteArray &) overload.
+ // So, we can make a shallow copy of chunk.
+ writeBuffer.append(*currentWriteChunk);
+ } else {
+ writeBuffer.append(data, size);
+ }
}
/*!
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index d8e12d7259..a485ec43b3 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -124,13 +124,14 @@ public:
QRingBufferRef writeBuffer;
qint64 pos;
qint64 devicePos;
+ qint64 transactionPos;
int readChannelCount;
int writeChannelCount;
int currentReadChannel;
int currentWriteChannel;
int readBufferChunkSize;
int writeBufferChunkSize;
- qint64 transactionPos;
+ const QByteArray *currentWriteChunk;
bool transactionStarted;
bool baseReadLineDataCalled;
@@ -175,6 +176,7 @@ public:
virtual qint64 peek(char *data, qint64 maxSize);
virtual QByteArray peek(qint64 maxSize);
qint64 skipByReading(qint64 maxSize);
+ void write(const char *data, qint64 size);
#ifdef QT_NO_QOBJECT
QIODevice *q_ptr;
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index b56ead8584..8e8664fda4 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1899,7 +1899,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
}
#endif
- d->writeBuffer.append(data, len);
+ d->write(data, len);
#ifdef Q_OS_WIN
if (!d->stdinWriteTrigger->isActive())
d->stdinWriteTrigger->start();
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index cf6a7672fb..3bde2215ad 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -2542,7 +2542,7 @@ qint64 QAbstractSocket::writeData(const char *data, qint64 size)
// We just write to our write buffer and enable the write notifier
// The write notifier then flush()es the buffer.
- d->writeBuffer.append(data, size);
+ d->write(data, size);
qint64 written = size;
if (d->socketEngine && !d->writeBuffer.isEmpty())
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index b585bea625..e174952b96 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -214,7 +214,7 @@ qint64 QLocalSocket::writeData(const char *data, qint64 len)
Q_D(QLocalSocket);
if (len == 0)
return 0;
- d->writeBuffer.append(data, len);
+ d->write(data, len);
if (!d->pipeWriter) {
d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
connect(d->pipeWriter, &QWindowsPipeWriter::bytesWritten,
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index ab4ce1527e..c5444b139e 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1819,7 +1819,7 @@ qint64 QSslSocket::writeData(const char *data, qint64 len)
if (d->mode == UnencryptedMode && !d->autoStartHandshake)
return d->plainSocket->write(data, len);
- d->writeBuffer.append(data, len);
+ d->write(data, len);
// make sure we flush to the plain socket's buffer
if (!d->flushTriggered) {
diff --git a/tests/auto/other/toolsupport/tst_toolsupport.cpp b/tests/auto/other/toolsupport/tst_toolsupport.cpp
index 19b6adb4b3..fc3a13267e 100644
--- a/tests/auto/other/toolsupport/tst_toolsupport.cpp
+++ b/tests/auto/other/toolsupport/tst_toolsupport.cpp
@@ -126,9 +126,9 @@ void tst_toolsupport::offsets_data()
#ifdef Q_PROCESSOR_X86
// x86 32-bit has weird alignment rules. Refer to QtPrivate::AlignOf in
// qglobal.h for more details.
- data << 184 << 288;
+ data << 188 << 296;
#else
- data << 188 << 288;
+ data << 192 << 296;
#endif
}
#endif