diff options
Diffstat (limited to 'src/corelib/thread')
| -rw-r--r-- | src/corelib/thread/qfuture_impl.h | 9 | ||||
| -rw-r--r-- | src/corelib/thread/qfutureinterface.h | 4 | ||||
| -rw-r--r-- | src/corelib/thread/qreadwritelock.cpp | 8 |
3 files changed, 16 insertions, 5 deletions
diff --git a/src/corelib/thread/qfuture_impl.h b/src/corelib/thread/qfuture_impl.h index 371ee524d72..d6c185cd704 100644 --- a/src/corelib/thread/qfuture_impl.h +++ b/src/corelib/thread/qfuture_impl.h @@ -845,7 +845,7 @@ struct UnwrapHandler using NestedType = typename QtPrivate::Future<ResultType>::type; QFutureInterface<NestedType> promise(QFutureInterfaceBase::State::Pending); - outer->then([promise](const QFuture<ResultType> &outerFuture) mutable { + auto chain = outer->then([promise](const QFuture<ResultType> &outerFuture) mutable { // We use the .then([](QFuture<ResultType> outerFuture) {...}) version // (where outerFuture == *outer), to propagate the exception if the // outer future has failed. @@ -883,6 +883,13 @@ struct UnwrapHandler promise.reportCanceled(); promise.reportFinished(); }); + + // Inject the promise into the chain. + // We use a fake function as a continuation, since the promise is + // managed by the outer future + chain.d.setContinuation(ContinuationWrapper(std::move([](const QFutureInterfaceBase &) {})), + promise.d, QFutureInterfaceBase::ContinuationType::Then); + return promise.future(); } }; diff --git a/src/corelib/thread/qfutureinterface.h b/src/corelib/thread/qfutureinterface.h index 0b88013800e..ff17560d3a1 100644 --- a/src/corelib/thread/qfutureinterface.h +++ b/src/corelib/thread/qfutureinterface.h @@ -42,6 +42,8 @@ template<class Function, class ResultType> class FailureHandler; #endif +struct UnwrapHandler; + #if QT_CORE_REMOVED_SINCE(6, 10) void Q_CORE_EXPORT watchContinuationImpl(const QObject *context, QtPrivate::QSlotObjectBase *slotObj, @@ -187,6 +189,8 @@ private: friend class QtPrivate::FailureHandler; #endif + friend struct QtPrivate::UnwrapHandler; + #if QT_CORE_REMOVED_SINCE(6, 10) friend Q_CORE_EXPORT void QtPrivate::watchContinuationImpl( const QObject *context, QtPrivate::QSlotObjectBase *slotObj, QFutureInterfaceBase &fi); diff --git a/src/corelib/thread/qreadwritelock.cpp b/src/corelib/thread/qreadwritelock.cpp index 96e35dcb965..2a1af2315ca 100644 --- a/src/corelib/thread/qreadwritelock.cpp +++ b/src/corelib/thread/qreadwritelock.cpp @@ -234,14 +234,14 @@ QBasicReadWriteLock::contendedTryLockForRead(QDeadlineTimer timeout, void *dd) return d->recursiveLockForRead(timeout); auto lock = qt_unique_lock(d->mutex); - if (d != d_ptr.loadRelaxed()) { + if (QReadWriteLockPrivate *dd = d_ptr.loadAcquire(); d != dd) { // d_ptr has changed: this QReadWriteLock was unlocked before we had // time to lock d->mutex. // We are holding a lock to a mutex within a QReadWriteLockPrivate // that is already released (or even is already re-used). That's ok // because the QFreeList never frees them. // Just unlock d->mutex (at the end of the scope) and retry. - d = d_ptr.loadAcquire(); + d = dd; continue; } return d->lockForRead(lock, timeout); @@ -340,11 +340,11 @@ QBasicReadWriteLock::contendedTryLockForWrite(QDeadlineTimer timeout, void *dd) return d->recursiveLockForWrite(timeout); auto lock = qt_unique_lock(d->mutex); - if (d != d_ptr.loadRelaxed()) { + if (QReadWriteLockPrivate *dd = d_ptr.loadAcquire(); d != dd) { // The mutex was unlocked before we had time to lock the mutex. // We are holding to a mutex within a QReadWriteLockPrivate that is already released // (or even is already re-used) but that's ok because the QFreeList never frees them. - d = d_ptr.loadAcquire(); + d = dd; continue; } return d->lockForWrite(lock, timeout); |
