summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qvector/tst_qvector.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/tools/qvector/tst_qvector.cpp')
-rw-r--r--tests/auto/corelib/tools/qvector/tst_qvector.cpp279
1 files changed, 178 insertions, 101 deletions
diff --git a/tests/auto/corelib/tools/qvector/tst_qvector.cpp b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
index 7c1e22689e..7738a2c797 100644
--- a/tests/auto/corelib/tools/qvector/tst_qvector.cpp
+++ b/tests/auto/corelib/tools/qvector/tst_qvector.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include <QtTest/QtTest>
+#include <QAtomicInt>
+#include <QThread>
+#include <QSemaphore>
#include <qvector.h>
struct Movable {
@@ -47,21 +50,21 @@ struct Movable {
: i(input)
, state(Constructed)
{
- ++counter;
+ counter.fetchAndAddRelaxed(1);
}
Movable(const Movable &other)
: i(other.i)
, state(Constructed)
{
check(other.state, Constructed);
- ++counter;
+ counter.fetchAndAddRelaxed(1);
}
~Movable()
{
check(state, Constructed);
i = 0;
- --counter;
+ counter.fetchAndAddRelaxed(-1);
state = Destructed;
}
@@ -80,7 +83,7 @@ struct Movable {
return *this;
}
char i;
- static int counter;
+ static QAtomicInt counter;
private:
enum State { Constructed = 106, Destructed = 110 };
State state;
@@ -91,7 +94,7 @@ private:
}
};
-int Movable::counter = 0;
+QAtomicInt Movable::counter = 0;
QT_BEGIN_NAMESPACE
Q_DECLARE_TYPEINFO(Movable, Q_MOVABLE_TYPE);
QT_END_NAMESPACE
@@ -103,21 +106,21 @@ struct Custom {
, that(this)
, state(Constructed)
{
- ++counter;
+ counter.fetchAndAddRelaxed(1);
}
Custom(const Custom &other)
: that(this)
, state(Constructed)
{
check(&other);
- ++counter;
+ counter.fetchAndAddRelaxed(1);
this->i = other.i;
}
~Custom()
{
check(this);
i = 0;
- --counter;
+ counter.fetchAndAddRelaxed(-1);
state = Destructed;
}
@@ -135,7 +138,7 @@ struct Custom {
i = other.i;
return *this;
}
- static int counter;
+ static QAtomicInt counter;
char i; // used to identify orgin of an instance
private:
@@ -151,7 +154,7 @@ private:
QCOMPARE(c->state, Constructed);
}
};
-int Custom::counter = 0;
+QAtomicInt Custom::counter = 0;
Q_DECLARE_METATYPE(Custom);
@@ -271,6 +274,9 @@ private slots:
void detachInt() const;
void detachMovable() const;
void detachCustom() const;
+ void detachThreadSafetyInt() const;
+ void detachThreadSafetyMovable() const;
+ void detachThreadSafetyCustom() const;
private:
template<typename T> void copyConstructor() const;
@@ -294,6 +300,7 @@ private:
template<typename T> void setSharable_data() const;
template<typename T> void setSharable() const;
template<typename T> void detach() const;
+ template<typename T> void detachThreadSafety() const;
};
@@ -415,16 +422,16 @@ void tst_QVector::copyConstructorInt() const
void tst_QVector::copyConstructorMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
copyConstructor<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::copyConstructorCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
copyConstructor<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -465,16 +472,16 @@ void tst_QVector::addInt() const
void tst_QVector::addMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
add<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::addCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
add<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -523,16 +530,16 @@ void tst_QVector::appendInt() const
void tst_QVector::appendMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
append<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::appendCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
append<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::at() const
@@ -602,16 +609,16 @@ void tst_QVector::capacityInt() const
void tst_QVector::capacityMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
capacity<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::capacityCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
capacity<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -633,16 +640,16 @@ void tst_QVector::clearInt() const
void tst_QVector::clearMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
clear<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::clearCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
clear<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::constData() const
@@ -717,16 +724,16 @@ void tst_QVector::countInt() const
void tst_QVector::countMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
count<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::countCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
count<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::data() const
@@ -771,16 +778,16 @@ void tst_QVector::emptyInt() const
void tst_QVector::emptyMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
empty<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::emptyCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
empty<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::endsWith() const
@@ -826,16 +833,16 @@ void tst_QVector::eraseEmptyInt() const
void tst_QVector::eraseEmptyMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
eraseEmpty<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::eraseEmptyCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
eraseEmpty<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -863,16 +870,16 @@ void tst_QVector::eraseEmptyReservedInt() const
void tst_QVector::eraseEmptyReservedMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
eraseEmptyReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::eraseEmptyReservedCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
eraseEmptyReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -986,30 +993,30 @@ void tst_QVector::eraseIntShared() const
void tst_QVector::eraseMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
erase<Movable>(false);
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::eraseMovableShared() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
erase<Movable>(true);
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::eraseCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
erase<Custom>(false);
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::eraseCustomShared() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
erase<Custom>(true);
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T> void tst_QVector::eraseReserved() const
@@ -1062,16 +1069,16 @@ void tst_QVector::eraseReservedInt() const
void tst_QVector::eraseReservedMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
eraseReserved<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::eraseReservedCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
eraseReserved<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -1102,16 +1109,16 @@ void tst_QVector::fillInt() const
void tst_QVector::fillMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
fill<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::fillCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
fill<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::first() const
@@ -1152,16 +1159,16 @@ void tst_QVector::fromListInt() const
void tst_QVector::fromListMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
fromList<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::fromListCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
fromList<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::fromStdVector() const
@@ -1338,16 +1345,16 @@ void tst_QVector::prependInt() const
void tst_QVector::prependMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
prepend<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::prependCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
prepend<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -1374,16 +1381,16 @@ void tst_QVector::removeInt() const
void tst_QVector::removeMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
remove<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::removeCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
remove<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::resizePOD_data() const
@@ -1510,7 +1517,7 @@ void tst_QVector::resizeComplexMovable_data() const
void tst_QVector::resizeComplexMovable() const
{
- const int items = Movable::counter;
+ const int items = Movable::counter.loadAcquire();
{
QFETCH(QVector<Movable>, vector);
QFETCH(int, size);
@@ -1529,7 +1536,7 @@ void tst_QVector::resizeComplexMovable() const
QCOMPARE(vector.size(), 0);
QVERIFY(vector.capacity() <= capacity);
}
- QCOMPARE(items, Movable::counter);
+ QCOMPARE(items, Movable::counter.loadAcquire());
}
void tst_QVector::resizeComplex_data() const
@@ -1585,7 +1592,7 @@ void tst_QVector::resizeComplex_data() const
void tst_QVector::resizeComplex() const
{
- const int items = Custom::counter;
+ const int items = Custom::counter.loadAcquire();
{
QFETCH(QVector<Custom>, vector);
QFETCH(int, size);
@@ -1604,12 +1611,12 @@ void tst_QVector::resizeComplex() const
QVERIFY(vector.isEmpty());
QVERIFY(vector.capacity() <= capacity);
}
- QCOMPARE(Custom::counter, items);
+ QCOMPARE(Custom::counter.loadAcquire(), items);
}
void tst_QVector::resizeCtorAndDtor() const
{
- const int items = Custom::counter;
+ const int items = Custom::counter.loadAcquire();
{
QVector<Custom> null;
QVector<Custom> empty(0, '0');
@@ -1631,7 +1638,7 @@ void tst_QVector::resizeCtorAndDtor() const
nonEmpty.resize(0);
nonEmptyReserved.resize(2);
}
- QCOMPARE(Custom::counter, items);
+ QCOMPARE(Custom::counter.loadAcquire(), items);
}
template<typename T>
@@ -1661,16 +1668,16 @@ void tst_QVector::sizeInt() const
void tst_QVector::sizeMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
size<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::sizeCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
size<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
// ::squeeze() is tested in ::capacity().
@@ -1720,16 +1727,16 @@ void tst_QVector::swapInt() const
void tst_QVector::swapMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
swap<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::swapCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
swap<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::toList() const
@@ -1947,16 +1954,16 @@ void tst_QVector::initializeListInt()
void tst_QVector::initializeListMovable()
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
initializeList<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::initializeListCustom()
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
initializeList<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
void tst_QVector::const_shared_null()
@@ -2084,16 +2091,16 @@ void tst_QVector::setSharableInt()
void tst_QVector::setSharableMovable()
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
setSharable<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::setSharableCustom()
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
setSharable<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
template<typename T>
@@ -2200,17 +2207,87 @@ void tst_QVector::detachInt() const
void tst_QVector::detachMovable() const
{
- const int instancesCount = Movable::counter;
+ const int instancesCount = Movable::counter.loadAcquire();
detach<Movable>();
- QCOMPARE(instancesCount, Movable::counter);
+ QCOMPARE(instancesCount, Movable::counter.loadAcquire());
}
void tst_QVector::detachCustom() const
{
- const int instancesCount = Custom::counter;
+ const int instancesCount = Custom::counter.loadAcquire();
detach<Custom>();
- QCOMPARE(instancesCount, Custom::counter);
+ QCOMPARE(instancesCount, Custom::counter.loadAcquire());
}
-QTEST_APPLESS_MAIN(tst_QVector)
+static QAtomicPointer<QVector<int> > detachThreadSafetyDataInt;
+static QAtomicPointer<QVector<Movable> > detachThreadSafetyDataMovable;
+static QAtomicPointer<QVector<Custom> > detachThreadSafetyDataCustom;
+
+template<typename T> QAtomicPointer<QVector<T> > *detachThreadSafetyData();
+template<> QAtomicPointer<QVector<int> > *detachThreadSafetyData() { return &detachThreadSafetyDataInt; }
+template<> QAtomicPointer<QVector<Movable> > *detachThreadSafetyData() { return &detachThreadSafetyDataMovable; }
+template<> QAtomicPointer<QVector<Custom> > *detachThreadSafetyData() { return &detachThreadSafetyDataCustom; }
+
+static QSemaphore detachThreadSafetyLock;
+
+template<typename T>
+void tst_QVector::detachThreadSafety() const
+{
+ delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(new QVector<T>(SimpleValue<T>::vector(400)));
+
+ static const uint threadsCount = 5;
+
+ struct : QThread {
+ void run() Q_DECL_OVERRIDE
+ {
+ QVector<T> copy(*detachThreadSafetyData<T>()->load());
+ QVERIFY(!copy.isDetached());
+ detachThreadSafetyLock.release();
+ detachThreadSafetyLock.acquire(100);
+ copy.detach();
+ }
+ } threads[threadsCount];
+
+ for (uint i = 0; i < threadsCount; ++i)
+ threads[i].start();
+ QThread::yieldCurrentThread();
+ detachThreadSafetyLock.acquire(threadsCount);
+
+ // destroy static original data
+ delete detachThreadSafetyData<T>()->fetchAndStoreOrdered(0);
+
+ QVERIFY(threadsCount < 100);
+ detachThreadSafetyLock.release(threadsCount * 100);
+ QThread::yieldCurrentThread();
+
+ for (uint i = 0; i < threadsCount; ++i)
+ threads[i].wait();
+}
+
+void tst_QVector::detachThreadSafetyInt() const
+{
+ for (uint i = 0; i < 128; ++i)
+ detachThreadSafety<int>();
+}
+
+void tst_QVector::detachThreadSafetyMovable() const
+{
+ const int instancesCount = Movable::counter.loadAcquire();
+ for (uint i = 0; i < 128; ++i) {
+ detachThreadSafety<Movable>();
+ QCOMPARE(Movable::counter.loadAcquire(), instancesCount);
+ }
+}
+
+void tst_QVector::detachThreadSafetyCustom() const
+{
+ const int instancesCount = Custom::counter.loadAcquire();
+ for (uint i = 0; i < 128; ++i) {
+ detachThreadSafety<Custom>();
+ QCOMPARE(Custom::counter.loadAcquire(), instancesCount);
+ }
+}
+
+
+QTEST_MAIN(tst_QVector)
#include "tst_qvector.moc"