diff options
Diffstat (limited to 'src/corelib/kernel/qobject.cpp')
-rw-r--r-- | src/corelib/kernel/qobject.cpp | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 9a2129a05d..1de6070388 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -510,6 +510,13 @@ bool QObjectPrivate::maybeSignalConnected(uint signalIndex) const return false; } +void QObjectPrivate::reinitBindingStorageAfterThreadMove() +{ + bindingStorage.reinitAfterThreadMove(); + for (int i = 0; i < children.size(); ++i) + children[i]->d_func()->reinitBindingStorageAfterThreadMove(); +} + /*! \internal */ @@ -997,6 +1004,16 @@ QObject::~QObject() d->wasDeleted = true; d->blockSig = 0; // unblock signals so we always emit destroyed() + if (!d->bindingStorage.isValid()) { + // this might be the case after an incomplete thread-move + // remove this object from the pending list in that case + if (QThread *ownThread = thread()) { + auto *privThread = static_cast<QThreadPrivate *>( + QObjectPrivate::get(ownThread)); + privThread->removeObjectWithPendingBindingStatusChange(this); + } + } + // If we reached this point, we need to clear the binding data // as the corresponding properties are no longer useful d->clearBindingStorage(); @@ -1018,7 +1035,7 @@ QObject::~QObject() emit destroyed(this); } - if (d->declarativeData && QAbstractDeclarativeData::destroyed) + if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::destroyed) QAbstractDeclarativeData::destroyed(d->declarativeData, this); QObjectPrivate::ConnectionData *cd = d->connections.loadRelaxed(); @@ -1641,7 +1658,16 @@ void QObject::moveToThread(QThread *targetThread) currentData->ref(); // move the object - d_func()->setThreadData_helper(currentData, targetData); + auto threadPrivate = targetThread + ? static_cast<QThreadPrivate *>(QThreadPrivate::get(targetThread)) + : nullptr; + QBindingStatus *bindingStatus = threadPrivate + ? threadPrivate->bindingStatus() + : nullptr; + if (threadPrivate && !bindingStatus) { + bindingStatus = threadPrivate->addObjectWithPendingBindingStatusChange(this); + } + d_func()->setThreadData_helper(currentData, targetData, bindingStatus); locker.unlock(); @@ -1654,16 +1680,22 @@ void QObjectPrivate::moveToThread_helper() Q_Q(QObject); QEvent e(QEvent::ThreadChange); QCoreApplication::sendEvent(q, &e); + bindingStorage.clear(); for (int i = 0; i < children.size(); ++i) { QObject *child = children.at(i); child->d_func()->moveToThread_helper(); } } -void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData) +void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData *targetData, QBindingStatus *status) { Q_Q(QObject); + if (status) { + // the new thread is already running + this->bindingStorage.bindingStatus = status; + } + // move posted events int eventsMoved = 0; for (int i = 0; i < currentData->postEventList.size(); ++i) { @@ -1718,7 +1750,7 @@ void QObjectPrivate::setThreadData_helper(QThreadData *currentData, QThreadData for (int i = 0; i < children.size(); ++i) { QObject *child = children.at(i); - child->d_func()->setThreadData_helper(currentData, targetData); + child->d_func()->setThreadData_helper(currentData, targetData, status); } } @@ -2560,7 +2592,7 @@ int QObject::receivers(const char *signal) const if (!d->isSignalConnected(signal_index)) return receivers; - if (d->declarativeData && QAbstractDeclarativeData::receivers) { + if (!d->isDeletingChildren && d->declarativeData && QAbstractDeclarativeData::receivers) { receivers += QAbstractDeclarativeData::receivers(d->declarativeData, this, signal_index); } |