summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/tools/qarraydata
diff options
context:
space:
mode:
authorJoão Abecasis <joao.abecasis@nokia.com>2011-11-25 11:09:09 +0100
committerQt by Nokia <qt-info@nokia.com>2012-01-05 13:59:14 +0100
commit9a890a519e9e314b99ca765a7127aa8bdc5b8870 (patch)
tree0d48e04b269d2a22359d0eb68fa3f3540646cf17 /tests/auto/corelib/tools/qarraydata
parent3fad9a846f6a89bd342b25c319d0263794bda575 (diff)
Add support for setSharable in RefCount
A reference count of 0 (zero) would never change. RefCount::deref to zero would return false (resource should be freed), subsequent calls on the same state would return true and not change state. While safe from RefCount's side, calling deref on a reference count of zero potentially indicated a dangling reference. With this change, a reference count of 0 is now abused to imply a non-sharable instance (cf. QVector::setSharable). This instance is to be deleted upon deref(), as the data is not shared and has a single owner. In practice, this means an (intentional) change in behaviour in that deref'ing zero still won't change state, but will return false, turning previous access to dangling references into double free errors. Users of RefCount wanting to support non-sharable instances are required to check the return of RefCount::ref() and use RefCount::isShared() to determine whether to detach (instead of directly checking count == 1). New functions are introduced to determine whether RefCount indicates a "Static" (permanent, typically read-only) or "Sharable" instance and whether the instance is currently "Shared" and requires detaching prior to accepting modifications.. This change formalizes -1 as the value used to flag persistent, read-only instances, no longer reserving the full negative domain. The concrete value is part of the ABI, but not of the API. (isStatic and Q_REFCOUNT_INITIALIZE_STATIC are part of the API, instead) Change-Id: I9a63c844155319bef0411e02b47f9d92476afefe Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Diffstat (limited to 'tests/auto/corelib/tools/qarraydata')
-rw-r--r--tests/auto/corelib/tools/qarraydata/simplevector.h2
-rw-r--r--tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp63
2 files changed, 60 insertions, 5 deletions
diff --git a/tests/auto/corelib/tools/qarraydata/simplevector.h b/tests/auto/corelib/tools/qarraydata/simplevector.h
index 38f61189da..c5e19f3c55 100644
--- a/tests/auto/corelib/tools/qarraydata/simplevector.h
+++ b/tests/auto/corelib/tools/qarraydata/simplevector.h
@@ -86,6 +86,8 @@ public:
bool isNull() const { return d.isNull(); }
bool isEmpty() const { return this->empty(); }
+ bool isStatic() const { return d->ref.isStatic(); }
+ bool isShared() const { return d->ref.isShared(); }
bool isSharedWith(const SimpleVector &other) const { return d == other.d; }
size_t size() const { return d->size; }
diff --git a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
index 241ef3b3e0..89a1f8bc75 100644
--- a/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
+++ b/tests/auto/corelib/tools/qarraydata/tst_qarraydata.cpp
@@ -72,13 +72,16 @@ void tst_QArrayData::referenceCounting()
QCOMPARE(int(array.ref), 1);
- array.ref.ref();
+ QVERIFY(!array.ref.isStatic());
+ QVERIFY(array.ref.isSharable());
+
+ QVERIFY(array.ref.ref());
QCOMPARE(int(array.ref), 2);
QVERIFY(array.ref.deref());
QCOMPARE(int(array.ref), 1);
- array.ref.ref();
+ QVERIFY(array.ref.ref());
QCOMPARE(int(array.ref), 2);
QVERIFY(array.ref.deref());
@@ -91,12 +94,34 @@ void tst_QArrayData::referenceCounting()
}
{
+ // Reference counting initialized to 0 (non-sharable)
+ QArrayData array = { { Q_BASIC_ATOMIC_INITIALIZER(0) }, 0, 0, 0, 0 };
+
+ QCOMPARE(int(array.ref), 0);
+
+ QVERIFY(!array.ref.isStatic());
+ QVERIFY(!array.ref.isSharable());
+
+ QVERIFY(!array.ref.ref());
+ // Reference counting fails, data should be copied
+ QCOMPARE(int(array.ref), 0);
+
+ QVERIFY(!array.ref.deref());
+ QCOMPARE(int(array.ref), 0);
+
+ // Free/release data
+ }
+
+ {
// Reference counting initialized to -1 (static read-only data)
QArrayData array = { Q_REFCOUNT_INITIALIZE_STATIC, 0, 0, 0, 0 };
QCOMPARE(int(array.ref), -1);
- array.ref.ref();
+ QVERIFY(array.ref.isStatic());
+ QVERIFY(array.ref.isSharable());
+
+ QVERIFY(array.ref.ref());
QCOMPARE(int(array.ref), -1);
QVERIFY(array.ref.deref());
@@ -109,11 +134,19 @@ void tst_QArrayData::sharedNullEmpty()
QArrayData *null = const_cast<QArrayData *>(&QArrayData::shared_null);
QArrayData *empty = const_cast<QArrayData *>(&QArrayData::shared_empty);
+ QVERIFY(null->ref.isStatic());
+ QVERIFY(null->ref.isSharable());
+ QVERIFY(null->ref.isShared());
+
+ QVERIFY(empty->ref.isStatic());
+ QVERIFY(empty->ref.isSharable());
+ QVERIFY(empty->ref.isShared());
+
QCOMPARE(int(null->ref), -1);
QCOMPARE(int(empty->ref), -1);
- null->ref.ref();
- empty->ref.ref();
+ QVERIFY(null->ref.ref());
+ QVERIFY(empty->ref.ref());
QCOMPARE(int(null->ref), -1);
QCOMPARE(int(empty->ref), -1);
@@ -218,6 +251,26 @@ void tst_QArrayData::simpleVector()
QVERIFY(v7.capacity() >= size_t(10));
QVERIFY(v8.capacity() >= size_t(10));
+ QVERIFY(v1.isStatic());
+ QVERIFY(v2.isStatic());
+ QVERIFY(v3.isStatic());
+ QVERIFY(v4.isStatic());
+ QVERIFY(v5.isStatic());
+ QVERIFY(v6.isStatic());
+ QVERIFY(!v7.isStatic());
+ QVERIFY(!v8.isStatic());
+
+ QVERIFY(v1.isShared());
+ QVERIFY(v2.isShared());
+ QVERIFY(v3.isShared());
+ QVERIFY(v4.isShared());
+ QVERIFY(v5.isShared());
+ QVERIFY(v6.isShared());
+ QVERIFY(!v7.isShared());
+ QVERIFY((SimpleVector<int>(v7), v7.isShared()));
+ QVERIFY(!v7.isShared());
+ QVERIFY(!v8.isShared());
+
QVERIFY(v1.isSharedWith(v2));
QVERIFY(v1.isSharedWith(v3));
QVERIFY(!v1.isSharedWith(v4));