Remove cast and assignment operators from QAtomicInt and QAtomicPointer
This is a source incompatible change. There is concern that the convenience of the implicit cast and assignment operators can lead to misuse. Several commits have already been done that remove excess use of the implicit cast, which is a *volatile* read every time it's used. Users of the QAtomic* API should have to think about when they are loading the value, and if they do or don't need the acquire memory barrier on load. The code that people would write using this API is meant to be multi-threaded, concurrent, and correct. The API should not allow them to inadvertently, possibly unknowingly, shoot themselves in the foot. SC-break-rubber-stamped-by: Lars Knoll Change-Id: I88fbc26d9db7b5ec80a58ad6271ffa13bbfd191f Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
3a72240d86
commit
409b3b42a2
@ -78,43 +78,12 @@ public:
|
|||||||
store(other.load());
|
store(other.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline QAtomicInt &operator=(int value)
|
|
||||||
{
|
|
||||||
this->store(value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QAtomicInt &operator=(const QAtomicInt &other)
|
inline QAtomicInt &operator=(const QAtomicInt &other)
|
||||||
{
|
{
|
||||||
this->store(other.load());
|
this->store(other.load());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator==(int value) const
|
|
||||||
{
|
|
||||||
return this->load() == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator!=(int value) const
|
|
||||||
{
|
|
||||||
return this->load() != value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline operator int() const
|
|
||||||
{
|
|
||||||
return this->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator!() const
|
|
||||||
{
|
|
||||||
return !this->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef qdoc
|
#ifdef qdoc
|
||||||
static bool isReferenceCountingNative();
|
static bool isReferenceCountingNative();
|
||||||
static bool isReferenceCountingWaitFree();
|
static bool isReferenceCountingWaitFree();
|
||||||
@ -168,49 +137,12 @@ public:
|
|||||||
this->store(other.load());
|
this->store(other.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline QAtomicPointer<T> &operator=(T *value)
|
|
||||||
{
|
|
||||||
this->store(value);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other)
|
inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other)
|
||||||
{
|
{
|
||||||
this->store(other.load());
|
this->store(other.load());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator==(T *value) const
|
|
||||||
{
|
|
||||||
return this->load() == value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator!=(T *value) const
|
|
||||||
{
|
|
||||||
return this->load() != value;
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline bool operator!() const
|
|
||||||
{
|
|
||||||
return !this->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline operator T *() const
|
|
||||||
{
|
|
||||||
return this->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
Q_DECL_DEPRECATED
|
|
||||||
inline T *operator->() const
|
|
||||||
{
|
|
||||||
return this->load();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef qdoc
|
#ifdef qdoc
|
||||||
static bool isTestAndSetNative();
|
static bool isTestAndSetNative();
|
||||||
static bool isTestAndSetWaitFree();
|
static bool isTestAndSetWaitFree();
|
||||||
|
@ -61,14 +61,6 @@ private slots:
|
|||||||
void constructor();
|
void constructor();
|
||||||
void copy_constructor_data();
|
void copy_constructor_data();
|
||||||
void copy_constructor();
|
void copy_constructor();
|
||||||
void equality_operator_data();
|
|
||||||
void equality_operator();
|
|
||||||
void inequality_operator_data();
|
|
||||||
void inequality_operator();
|
|
||||||
void not_operator_data();
|
|
||||||
void not_operator();
|
|
||||||
void cast_operator_data();
|
|
||||||
void cast_operator();
|
|
||||||
void assignment_operator_data();
|
void assignment_operator_data();
|
||||||
void assignment_operator();
|
void assignment_operator();
|
||||||
|
|
||||||
@ -185,71 +177,6 @@ void tst_QAtomicInt::copy_constructor()
|
|||||||
QCOMPARE(atomic5.load(), value);
|
QCOMPARE(atomic5.load(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAtomicInt::equality_operator_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<int>("value1");
|
|
||||||
QTest::addColumn<int>("value2");
|
|
||||||
QTest::addColumn<int>("result");
|
|
||||||
|
|
||||||
QTest::newRow("success0") << 1 << 1 << 1;
|
|
||||||
QTest::newRow("success1") << -1 << -1 << 1;
|
|
||||||
QTest::newRow("failure0") << 0 << 1 << 0;
|
|
||||||
QTest::newRow("failure1") << 1 << 0 << 0;
|
|
||||||
QTest::newRow("failure2") << 0 << -1 << 0;
|
|
||||||
QTest::newRow("failure3") << -1 << 0 << 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::equality_operator()
|
|
||||||
{
|
|
||||||
QFETCH(int, value1);
|
|
||||||
QFETCH(int, value2);
|
|
||||||
QAtomicInt x = value1;
|
|
||||||
QTEST(x == value2 ? 1 : 0, "result");
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::inequality_operator_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<int>("value1");
|
|
||||||
QTest::addColumn<int>("value2");
|
|
||||||
QTest::addColumn<int>("result");
|
|
||||||
|
|
||||||
QTest::newRow("failure0") << 1 << 1 << 0;
|
|
||||||
QTest::newRow("failure1") << -1 << -1 << 0;
|
|
||||||
QTest::newRow("success0") << 0 << 1 << 1;
|
|
||||||
QTest::newRow("success1") << 1 << 0 << 1;
|
|
||||||
QTest::newRow("success2") << 0 << -1 << 1;
|
|
||||||
QTest::newRow("success3") << -1 << 0 << 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::inequality_operator()
|
|
||||||
{
|
|
||||||
QFETCH(int, value1);
|
|
||||||
QFETCH(int, value2);
|
|
||||||
QAtomicInt x = value1;
|
|
||||||
QTEST(x != value2 ? 1 : 0, "result");
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::not_operator_data()
|
|
||||||
{ constructor_data(); }
|
|
||||||
|
|
||||||
void tst_QAtomicInt::not_operator()
|
|
||||||
{
|
|
||||||
QFETCH(int, value);
|
|
||||||
QAtomicInt atomic = value;
|
|
||||||
QCOMPARE(!atomic, !value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::cast_operator_data()
|
|
||||||
{ constructor_data(); }
|
|
||||||
|
|
||||||
void tst_QAtomicInt::cast_operator()
|
|
||||||
{
|
|
||||||
QFETCH(int, value);
|
|
||||||
QAtomicInt atomic = value;
|
|
||||||
int copy = atomic;
|
|
||||||
QCOMPARE(copy, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicInt::assignment_operator_data()
|
void tst_QAtomicInt::assignment_operator_data()
|
||||||
{
|
{
|
||||||
QTest::addColumn<int>("value");
|
QTest::addColumn<int>("value");
|
||||||
@ -271,9 +198,9 @@ void tst_QAtomicInt::assignment_operator()
|
|||||||
{
|
{
|
||||||
QAtomicInt atomic1 = value;
|
QAtomicInt atomic1 = value;
|
||||||
atomic1 = newval;
|
atomic1 = newval;
|
||||||
QCOMPARE(int(atomic1), newval);
|
QCOMPARE(atomic1.load(), newval);
|
||||||
atomic1 = value;
|
atomic1 = value;
|
||||||
QCOMPARE(int(atomic1), value);
|
QCOMPARE(atomic1.load(), value);
|
||||||
|
|
||||||
QAtomicInt atomic2 = newval;
|
QAtomicInt atomic2 = newval;
|
||||||
atomic1 = atomic2;
|
atomic1 = atomic2;
|
||||||
|
@ -55,11 +55,7 @@ private slots:
|
|||||||
|
|
||||||
void constructor();
|
void constructor();
|
||||||
void copy_constructor();
|
void copy_constructor();
|
||||||
void equality_operator();
|
|
||||||
void inequality_operator();
|
|
||||||
void assignment_operator();
|
void assignment_operator();
|
||||||
void star_operator();
|
|
||||||
void dereference_operator();
|
|
||||||
|
|
||||||
void isTestAndSetNative();
|
void isTestAndSetNative();
|
||||||
void isTestAndSetWaitFree();
|
void isTestAndSetWaitFree();
|
||||||
@ -157,52 +153,6 @@ void tst_QAtomicPointer::copy_constructor()
|
|||||||
QCOMPARE(atomic3_copy.load(), atomic3.load());
|
QCOMPARE(atomic3_copy.load(), atomic3.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAtomicPointer::equality_operator()
|
|
||||||
{
|
|
||||||
void *one = this;
|
|
||||||
void *two = &one;
|
|
||||||
void *three = &two;
|
|
||||||
|
|
||||||
QAtomicPointer<void> atomic1 = one;
|
|
||||||
QAtomicPointer<void> atomic2 = two;
|
|
||||||
QAtomicPointer<void> atomic3 = three;
|
|
||||||
|
|
||||||
QVERIFY(atomic1 == one);
|
|
||||||
QVERIFY(!(atomic1 == two));
|
|
||||||
QVERIFY(!(atomic1 == three));
|
|
||||||
|
|
||||||
QVERIFY(!(atomic2 == one));
|
|
||||||
QVERIFY(atomic2 == two);
|
|
||||||
QVERIFY(!(atomic2 == three));
|
|
||||||
|
|
||||||
QVERIFY(!(atomic3 == one));
|
|
||||||
QVERIFY(!(atomic3 == two));
|
|
||||||
QVERIFY(atomic3 == three);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicPointer::inequality_operator()
|
|
||||||
{
|
|
||||||
void *one = this;
|
|
||||||
void *two = &one;
|
|
||||||
void *three = &two;
|
|
||||||
|
|
||||||
QAtomicPointer<void> atomic1 = one;
|
|
||||||
QAtomicPointer<void> atomic2 = two;
|
|
||||||
QAtomicPointer<void> atomic3 = three;
|
|
||||||
|
|
||||||
QVERIFY(!(atomic1 != one));
|
|
||||||
QVERIFY(atomic1 != two);
|
|
||||||
QVERIFY(atomic1 != three);
|
|
||||||
|
|
||||||
QVERIFY(atomic2 != one);
|
|
||||||
QVERIFY(!(atomic2 != two));
|
|
||||||
QVERIFY(atomic2 != three);
|
|
||||||
|
|
||||||
QVERIFY(atomic3 != one);
|
|
||||||
QVERIFY(atomic3 != two);
|
|
||||||
QVERIFY(!(atomic3 != three));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicPointer::assignment_operator()
|
void tst_QAtomicPointer::assignment_operator()
|
||||||
{
|
{
|
||||||
void *one = this;
|
void *one = this;
|
||||||
@ -213,37 +163,17 @@ void tst_QAtomicPointer::assignment_operator()
|
|||||||
QAtomicPointer<void> atomic2 = two;
|
QAtomicPointer<void> atomic2 = two;
|
||||||
QAtomicPointer<void> atomic3 = three;
|
QAtomicPointer<void> atomic3 = three;
|
||||||
|
|
||||||
QVERIFY(atomic1 == one);
|
QVERIFY(atomic1.load() == one);
|
||||||
QVERIFY(atomic2 == two);
|
QVERIFY(atomic2.load() == two);
|
||||||
QVERIFY(atomic3 == three);
|
QVERIFY(atomic3.load() == three);
|
||||||
|
|
||||||
atomic1 = two;
|
atomic1 = two;
|
||||||
atomic2 = three;
|
atomic2 = three;
|
||||||
atomic3 = one;
|
atomic3 = one;
|
||||||
|
|
||||||
QVERIFY(atomic1 == two);
|
QVERIFY(atomic1.load() == two);
|
||||||
QVERIFY(atomic2 == three);
|
QVERIFY(atomic2.load() == three);
|
||||||
QVERIFY(atomic3 == one);
|
QVERIFY(atomic3.load() == one);
|
||||||
}
|
|
||||||
|
|
||||||
struct Type
|
|
||||||
{
|
|
||||||
inline const Type *self() const
|
|
||||||
{ return this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void tst_QAtomicPointer::star_operator()
|
|
||||||
{
|
|
||||||
Type t;
|
|
||||||
QAtomicPointer<Type> p = &t;
|
|
||||||
QCOMPARE((*p).self(), t.self());
|
|
||||||
}
|
|
||||||
|
|
||||||
void tst_QAtomicPointer::dereference_operator()
|
|
||||||
{
|
|
||||||
Type t;
|
|
||||||
QAtomicPointer<Type> p = &t;
|
|
||||||
QCOMPARE(p->self(), t.self());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_QAtomicPointer::isTestAndSetNative()
|
void tst_QAtomicPointer::isTestAndSetNative()
|
||||||
|
@ -1545,8 +1545,8 @@ void tst_QSharedPointer::threadStressTest()
|
|||||||
// verify that the count is the right range
|
// verify that the count is the right range
|
||||||
int minValue = strongThreadCount;
|
int minValue = strongThreadCount;
|
||||||
int maxValue = strongThreadCount + weakThreadCount;
|
int maxValue = strongThreadCount + weakThreadCount;
|
||||||
QVERIFY(counter >= minValue);
|
QVERIFY(counter.load() >= minValue);
|
||||||
QVERIFY(counter <= maxValue);
|
QVERIFY(counter.load() <= maxValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user