diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-10-25 07:53:45 +0000 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-10-25 15:56:54 +0000 |
commit | 342b37f3884e62f2097addda1aacb1d15be38bf7 (patch) | |
tree | 20d9f3515de2d34951ea284abd368668e0468dd7 | |
parent | 1af821825a4173532cf14024ea9bebc75bf3c62c (diff) |
Revert "QAtomic: remove the copy ctor and assignment operator"
This reverts commit 6a93ec2435b8a453d43956fef6afa5f091d70ffc.
Reason for revert: Breaks qtdeclarative build, submodules need
to be clean before we deprecate or remove APIs.
Change-Id: Id0726b9bfad6072065b380b44b6ff6dffda79e45
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | src/corelib/thread/qatomic.cpp | 27 | ||||
-rw-r--r-- | src/corelib/thread/qatomic.h | 34 | ||||
-rw-r--r-- | src/corelib/thread/qbasicatomic.h | 4 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp | 25 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp | 52 | ||||
-rw-r--r-- | tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp | 22 |
6 files changed, 157 insertions, 7 deletions
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp index 948f30bb98..4843556eb5 100644 --- a/src/corelib/thread/qatomic.cpp +++ b/src/corelib/thread/qatomic.cpp @@ -211,6 +211,20 @@ */ /*! + \fn template <typename T> QAtomicInteger<T>::QAtomicInteger(const QAtomicInteger &other) + + Constructs a copy of \a other. +*/ + +/*! + \fn template <typename T> QAtomicInteger &QAtomicInteger<T>::operator=(const QAtomicInteger &other) + + Assigns \a other to this QAtomicInteger and returns a reference to + this QAtomicInteger. +*/ + + +/*! \fn template <typename T> T QAtomicInteger<T>::loadRelaxed() const \since 5.14 @@ -1355,6 +1369,19 @@ */ /*! + \fn template <typename T> QAtomicPointer<T>::QAtomicPointer(const QAtomicPointer<T> &other) + + Constructs a copy of \a other. +*/ + +/*! + \fn template <typename T> QAtomicPointer &QAtomicPointer<T>::operator=(const QAtomicPointer &other) + + Assigns \a other to this QAtomicPointer and returns a reference to + this QAtomicPointer. +*/ + +/*! \fn template <typename T> T *QAtomicPointer<T>::loadRelaxed() const \since 5.14 diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h index 26369d28f8..7fe5ac69b9 100644 --- a/src/corelib/thread/qatomic.h +++ b/src/corelib/thread/qatomic.h @@ -17,8 +17,20 @@ template <typename T> class QAtomicInteger : public QBasicAtomicInteger<T> { public: + // Non-atomic API constexpr QAtomicInteger(T value = 0) noexcept : QBasicAtomicInteger<T>(value) {} - using QBasicAtomicInteger<T>::operator=; + + inline QAtomicInteger(const QAtomicInteger &other) noexcept + : QBasicAtomicInteger<T>() + { + this->storeRelease(other.loadAcquire()); + } + + inline QAtomicInteger &operator=(const QAtomicInteger &other) noexcept + { + this->storeRelease(other.loadAcquire()); + return *this; + } #ifdef Q_QDOC T loadRelaxed() const; @@ -96,12 +108,13 @@ public: #endif }; -// ### Qt 7: make QAtomicInt a typedef class QAtomicInt : public QAtomicInteger<int> { public: - using QAtomicInteger<int>::QAtomicInteger; - using QAtomicInteger<int>::operator=; + // Non-atomic API + // We could use QT_COMPILER_INHERITING_CONSTRUCTORS, but we need only one; + // the implicit definition for all the others is fine. + constexpr QAtomicInt(int value = 0) noexcept : QAtomicInteger<int>(value) {} }; // High-level atomic pointer operations @@ -110,7 +123,18 @@ class QAtomicPointer : public QBasicAtomicPointer<T> { public: constexpr QAtomicPointer(T *value = nullptr) noexcept : QBasicAtomicPointer<T>(value) {} - using QBasicAtomicPointer<T>::operator=; + + inline QAtomicPointer(const QAtomicPointer<T> &other) noexcept + : QBasicAtomicPointer<T>() + { + this->storeRelease(other.loadAcquire()); + } + + inline QAtomicPointer<T> &operator=(const QAtomicPointer<T> &other) noexcept + { + this->storeRelease(other.loadAcquire()); + return *this; + } #ifdef Q_QDOC T *loadAcquire() const; diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h index 4dd67f57c3..6d061ea49a 100644 --- a/src/corelib/thread/qbasicatomic.h +++ b/src/corelib/thread/qbasicatomic.h @@ -39,7 +39,7 @@ public: T loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); } void storeRelease(T newValue) noexcept { Ops::storeRelease(_q_value, newValue); } operator T() const noexcept { return loadAcquire(); } - QBasicAtomicInteger &operator=(T newValue) noexcept { storeRelease(newValue); return *this; } + T operator=(T newValue) noexcept { storeRelease(newValue); return newValue; } static constexpr bool isReferenceCountingNative() noexcept { return Ops::isReferenceCountingNative(); } static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); } @@ -171,7 +171,7 @@ public: void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); } operator Type() const noexcept { return loadAcquire(); } - QBasicAtomicPointer &operator=(Type newValue) noexcept { storeRelease(newValue); return *this; } + Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; } // Atomic API, implemented in qatomic_XXX.h Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); } diff --git a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp index 315256e471..e8606b2568 100644 --- a/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/corelib/thread/qatomicint/tst_qatomicint.cpp @@ -21,6 +21,8 @@ private slots: // QAtomicInt members void constructor_data(); void constructor(); + void copy_constructor_data(); + void copy_constructor(); void assignment_operator_data(); void assignment_operator(); @@ -234,6 +236,25 @@ void tst_QAtomicInt::constructor() QCOMPARE(atomic2.loadRelaxed(), value); } +void tst_QAtomicInt::copy_constructor_data() +{ constructor_data(); } + +void tst_QAtomicInt::copy_constructor() +{ + QFETCH(int, value); + QAtomicInt atomic1(value); + QCOMPARE(atomic1.loadRelaxed(), value); + + QAtomicInt atomic2(atomic1); + QCOMPARE(atomic2.loadRelaxed(), value); + QAtomicInt atomic3 = atomic1; + QCOMPARE(atomic3.loadRelaxed(), value); + QAtomicInt atomic4(atomic2); + QCOMPARE(atomic4.loadRelaxed(), value); + QAtomicInt atomic5 = atomic2; + QCOMPARE(atomic5.loadRelaxed(), value); +} + void tst_QAtomicInt::assignment_operator_data() { QTest::addColumn<int>("value"); @@ -258,6 +279,10 @@ void tst_QAtomicInt::assignment_operator() QCOMPARE(atomic1.loadRelaxed(), newval); atomic1 = value; QCOMPARE(atomic1.loadRelaxed(), value); + + QAtomicInt atomic2 = newval; + atomic1 = atomic2; + QCOMPARE(atomic1.loadRelaxed(), atomic2.loadRelaxed()); } } diff --git a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp index 1ac07de80f..4e3c93c4e9 100644 --- a/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp +++ b/tests/auto/corelib/thread/qatomicinteger/tst_qatomicinteger.cpp @@ -90,6 +90,12 @@ private Q_SLOTS: void constructor_data() { addData(); } void constructor(); + void copy_data() { addData(); } + void copy(); + + void assign_data() { addData(); } + void assign(); + void operatorInteger_data() { addData(); } void operatorInteger(); @@ -213,6 +219,52 @@ void tst_QAtomicIntegerXX::constructor() QVERIFY(atomic.loadRelaxed() <= std::numeric_limits<T>::max()); } +void tst_QAtomicIntegerXX::copy() +{ + QFETCH(LargeInt, value); + + QAtomicInteger<T> atomic(value); + QAtomicInteger<T> copy(atomic); + QCOMPARE(copy.loadRelaxed(), atomic.loadRelaxed()); + + QAtomicInteger<T> copy2 = atomic; + QCOMPARE(copy2.loadRelaxed(), atomic.loadRelaxed()); + + // move + QAtomicInteger<T> copy3(std::move(copy)); + QCOMPARE(copy3.loadRelaxed(), atomic.loadRelaxed()); + + QAtomicInteger<T> copy4 = std::move(copy2); + QCOMPARE(copy4.loadRelaxed(), atomic.loadRelaxed()); +} + +void tst_QAtomicIntegerXX::assign() +{ + QFETCH(LargeInt, value); + + QAtomicInteger<T> atomic(value); + QAtomicInteger<T> copy; + copy = atomic; + QCOMPARE(copy.loadRelaxed(), atomic.loadRelaxed()); + + QAtomicInteger<T> copy2; + copy2 = atomic; // operator=(const QAtomicInteger &) + QCOMPARE(copy2.loadRelaxed(), atomic.loadRelaxed()); + + QAtomicInteger<T> copy2bis; + copy2bis = atomic.loadRelaxed(); // operator=(T) + QCOMPARE(copy2bis.loadRelaxed(), atomic.loadRelaxed()); + + // move + QAtomicInteger<T> copy3; + copy3 = std::move(copy); + QCOMPARE(copy3.loadRelaxed(), atomic.loadRelaxed()); + + QAtomicInteger<T> copy4; + copy4 = std::move(copy2); + QCOMPARE(copy4.loadRelaxed(), atomic.loadRelaxed()); +} + void tst_QAtomicIntegerXX::operatorInteger() { QFETCH(LargeInt, value); diff --git a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp index 1113e73b1b..c6bd784270 100644 --- a/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/corelib/thread/qatomicpointer/tst_qatomicpointer.cpp @@ -15,6 +15,7 @@ private slots: void alignment(); void constructor(); + void copy_constructor(); void assignment_operator(); void isTestAndSetNative(); @@ -100,6 +101,27 @@ void tst_QAtomicPointer::constructor() QCOMPARE(atomic3.loadRelaxed(), three); } +void tst_QAtomicPointer::copy_constructor() +{ + void *one = this; + QAtomicPointer<void> atomic1 = one; + QAtomicPointer<void> atomic1_copy = atomic1; + QCOMPARE(atomic1_copy.loadRelaxed(), one); + QCOMPARE(atomic1_copy.loadRelaxed(), atomic1.loadRelaxed()); + + void *two = &one; + QAtomicPointer<void> atomic2 = two; + QAtomicPointer<void> atomic2_copy = atomic2; + QCOMPARE(atomic2_copy.loadRelaxed(), two); + QCOMPARE(atomic2_copy.loadRelaxed(), atomic2.loadRelaxed()); + + void *three = &two; + QAtomicPointer<void> atomic3 = three; + QAtomicPointer<void> atomic3_copy = atomic3; + QCOMPARE(atomic3_copy.loadRelaxed(), three); + QCOMPARE(atomic3_copy.loadRelaxed(), atomic3.loadRelaxed()); +} + void tst_QAtomicPointer::assignment_operator() { void *one = this; |