QObject: Let moveToThread return succcess state

Add bool QObjectPrivate::moveToThread() which returns the success state
of the attempt to move the object to the new thread. For Qt7 the public
signature of QObject::moveToThread() should be changed to directly
return this value.

[ChangeLog][QtCore][QObject] QObject::moveToThread() now returns a
boolean success state.

Change-Id: I8441c8155a76b804b473ab9c45c2be6840ef1677
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
(cherry picked from commit e752c77b35185fa51cdc3684329a9733abe2be3b)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Christian Ehrlicher 2024-01-20 22:30:30 +01:00 committed by Qt Cherry-pick Bot
parent a375e52aa3
commit f14f12c2e1
4 changed files with 23 additions and 12 deletions

View File

@ -852,6 +852,11 @@ QObject *qt_qFindChild_helper(const QObject *parent, const QString &name, const
return qt_qFindChild_helper(parent, QAnyStringView{name}, mo, options);
}
void QObject::moveToThread(QThread *targetThread)
{
moveToThread(targetThread, QT6_CALL_NEW_OVERLOAD);
}
#include "qobjectdefs.h"
int QMetaObject::indexOfEnumerator(const char *name) const

View File

@ -1628,9 +1628,9 @@ QThread *QObject::thread() const
}
/*!
Changes the thread affinity for this object and its children. The
object cannot be moved if it has a parent. Event processing will
continue in the \a targetThread.
Changes the thread affinity for this object and its children and
returns \c true on success. The object cannot be moved if it has a
parent. Event processing will continue in the \a targetThread.
To move an object to the main thread, use QApplication::instance()
to retrieve a pointer to the current application, and then use
@ -1667,26 +1667,26 @@ QThread *QObject::thread() const
\sa thread()
*/
void QObject::moveToThread(QThread *targetThread)
bool QObject::moveToThread(QThread *targetThread QT6_IMPL_NEW_OVERLOAD_TAIL)
{
Q_D(QObject);
if (d->threadData.loadRelaxed()->thread.loadAcquire() == targetThread) {
// object is already in this thread
return;
return true;
}
if (d->parent != nullptr) {
qWarning("QObject::moveToThread: Cannot move objects with a parent");
return;
return false;
}
if (d->isWidget) {
qWarning("QObject::moveToThread: Widgets cannot be moved to a new thread");
return;
return false;
}
if (!d->bindingStorage.isEmpty()) {
qWarning("QObject::moveToThread: Can not move objects that contain bindings or are used in bindings to a new thread.");
return;
return false;
}
QThreadData *currentData = QThreadData::current();
@ -1706,7 +1706,7 @@ void QObject::moveToThread(QThread *targetThread)
"DYLD_PRINT_LIBRARIES=1 and check that only one set of binaries are being loaded.");
#endif
return;
return false;
}
// prepare to move
@ -1740,6 +1740,7 @@ void QObject::moveToThread(QThread *targetThread)
// now currentData can commit suicide if it wants to
currentData->deref();
return true;
}
void QObjectPrivate::moveToThread_helper()

View File

@ -135,7 +135,10 @@ public:
bool blockSignals(bool b) noexcept;
QThread *thread() const;
#if QT_CORE_REMOVED_SINCE(6, 7)
void moveToThread(QThread *thread);
#endif
bool moveToThread(QThread *thread QT6_DECL_NEW_OVERLOAD_TAIL);
int startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer);
int startTimer(std::chrono::milliseconds time, Qt::TimerType timerType = Qt::CoarseTimer);

View File

@ -1870,13 +1870,15 @@ void tst_QObject::moveToThread()
QObject *child = new QObject(object);
QCOMPARE(object->thread(), currentThread);
QCOMPARE(child->thread(), currentThread);
object->moveToThread(0);
QVERIFY(object->moveToThread(nullptr));
QCOMPARE(object->thread(), (QThread *)0);
QCOMPARE(child->thread(), (QThread *)0);
object->moveToThread(currentThread);
QVERIFY(object->moveToThread(currentThread));
QCOMPARE(object->thread(), currentThread);
QCOMPARE(child->thread(), currentThread);
object->moveToThread(0);
QTest::ignoreMessage(QtWarningMsg, "QObject::moveToThread: Cannot move objects with a parent");
QVERIFY(!child->moveToThread(nullptr));
QVERIFY(object->moveToThread(nullptr));
QCOMPARE(object->thread(), (QThread *)0);
QCOMPARE(child->thread(), (QThread *)0);
// can delete an object with no thread anywhere