summaryrefslogtreecommitdiffstats
path: root/async
diff options
context:
space:
mode:
Diffstat (limited to 'async')
-rw-r--r--async/src/async.h16
1 files changed, 12 insertions, 4 deletions
diff --git a/async/src/async.h b/async/src/async.h
index 57879a7..2741341 100644
--- a/async/src/async.h
+++ b/async/src/async.h
@@ -114,6 +114,7 @@ public:
114protected: 114protected:
115 ExecutorBase(const ExecutorBasePtr &parent); 115 ExecutorBase(const ExecutorBasePtr &parent);
116 116
117 ExecutorBasePtr mSelf;
117 ExecutorBasePtr mPrev; 118 ExecutorBasePtr mPrev;
118 FutureBase *mResult; 119 FutureBase *mResult;
119 bool mIsRunning; 120 bool mIsRunning;
@@ -429,6 +430,11 @@ public:
429 430
430 Async::Future<Out> exec() 431 Async::Future<Out> exec()
431 { 432 {
433 // Have the top executor hold reference to itself during the execution.
434 // This ensures that even if the Job goes out of scope, the full Executor
435 // chain will not be destroyed.
436 // The executor will remove the self-reference once it's Future is finished.
437 mExecutor->mSelf = mExecutor;
432 mExecutor->exec(); 438 mExecutor->exec();
433 return result(); 439 return result();
434 } 440 }
@@ -471,7 +477,7 @@ private:
471 [watcher, &future]() { 477 [watcher, &future]() {
472 Async::detail::copyFutureValue(watcher->future(), future); 478 Async::detail::copyFutureValue(watcher->future(), future);
473 future.setFinished(); 479 future.setFinished();
474 watcher->deleteLater(); 480 delete watcher;
475 }); 481 });
476 watcher->setFuture(job.exec(in ...)); 482 watcher->setFuture(job.exec(in ...));
477 }; 483 };
@@ -569,10 +575,12 @@ void Executor<PrevOut, Out, In ...>::exec()
569 mResult = new Async::Future<Out>(); 575 mResult = new Async::Future<Out>();
570 auto fw = new Async::FutureWatcher<Out>(); 576 auto fw = new Async::FutureWatcher<Out>();
571 QObject::connect(fw, &Async::FutureWatcher<Out>::futureReady, 577 QObject::connect(fw, &Async::FutureWatcher<Out>::futureReady,
572 [&]() { 578 [fw, this]() {
573 mIsFinished = true; 579 mIsFinished = true;
574 fw->deleteLater(); 580 mSelf.clear();
581 delete fw;
575 }); 582 });
583 fw->setFuture(*static_cast<Async::Future<Out>*>(mResult));
576 584
577 if (!mPrevFuture || mPrevFuture->isFinished()) { 585 if (!mPrevFuture || mPrevFuture->isFinished()) {
578 if (mPrevFuture && mPrevFuture->errorCode() != 0) { 586 if (mPrevFuture && mPrevFuture->errorCode() != 0) {
@@ -593,7 +601,7 @@ void Executor<PrevOut, Out, In ...>::exec()
593 [futureWatcher, this]() { 601 [futureWatcher, this]() {
594 auto prevFuture = futureWatcher->future(); 602 auto prevFuture = futureWatcher->future();
595 assert(prevFuture.isFinished()); 603 assert(prevFuture.isFinished());
596 futureWatcher->deleteLater(); 604 delete futureWatcher;
597 if (prevFuture.errorCode() != 0) { 605 if (prevFuture.errorCode() != 0) {
598 if (mErrorFunc) { 606 if (mErrorFunc) {
599 mErrorFunc(prevFuture.errorCode(), prevFuture.errorMessage()); 607 mErrorFunc(prevFuture.errorCode(), prevFuture.errorMessage());