diff options
author | Alex Trotsenko <alex1973tr@gmail.com> | 2016-07-11 14:06:49 +0300 |
---|---|---|
committer | Alex Trotsenko <alex1973tr@gmail.com> | 2017-12-30 10:15:10 +0000 |
commit | 89b0364cded81457eaa264c1634af5d082da3c21 (patch) | |
tree | 2a99fe43f95a97a4140395106fb06221ed95ea1c /tests/auto/corelib/tools/qringbuffer | |
parent | 48ea14080ea0be33faa8a4390a89d501c807538a (diff) |
QRingBuffer: avoid reallocations of the data
Since its initial implementation, QRingBuffer had the following
fragilities in the architecture:
- it does not guarantee validity of the pointers, if new data will
be appended. As an example, passing an address of the QRingBuffer
chunk as a parameter to the WriteFileEx() function on Windows
requires the stability of the pointer. So, we can't add new data
to the QRingBuffer until the overlapped operation completed
(related issues were fixed for QWindowsPipeWriter and QSerialPort
in 5.6 branch by introducing an intermediate byte array);
- inefficient reallocations in reserve(), if a shared chunk was
inserted in the queue (we can get a reallocation in the place
where we don't expect it:
char *writePtr = buffers.last().data() + tail; <- line #133
).
Proposed solution is to avoid reallocation by allocating a new
block instead. That was accomplished by introducing a QRingChunk
class which operates on a fixed byte array and implements head/tail
pointers strategy for each individual buffer in the queue. So,
QRingBuffer is no longer dependent on QByteArray's internal
shrink/growth algorithms.
Change-Id: I05abab0ad78e22e4815a196037dfc6eff85325d1
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib/tools/qringbuffer')
-rw-r--r-- | tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp index deee7171b1..e355a7fcfb 100644 --- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp +++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp @@ -48,6 +48,7 @@ private slots: void reserveAndReadInPacketMode(); void reserveFrontAndRead(); void chop(); + void readPointerValidity(); void ungetChar(); void indexOf(); void appendAndRead(); @@ -303,6 +304,21 @@ void tst_QRingBuffer::chop() QVERIFY(memcmp(ringBuffer.readPointer(), "0123", 4) == 0); } +void tst_QRingBuffer::readPointerValidity() +{ + QRingBuffer ringBuffer(16); + QByteArray ba("Hello world!"); + + ringBuffer.append(ba); + const char *ptr = ringBuffer.readPointer(); + ba.clear(); + ringBuffer.reserve(32); + QVERIFY(ptr == ringBuffer.readPointer()); + ringBuffer.reserveFront(32); + qint64 dummy; + QVERIFY(ptr == ringBuffer.readPointerAtPosition(32, dummy)); +} + void tst_QRingBuffer::ungetChar() { QRingBuffer ringBuffer(16); |