diff options
Diffstat (limited to 'async/src')
-rw-r--r-- | async/src/async.h | 16 |
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: | |||
114 | protected: | 114 | protected: |
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()); |