diff options
author | Dan Vrátil <dvratil@redhat.com> | 2015-04-01 13:24:41 +0200 |
---|---|---|
committer | Dan Vrátil <dvratil@redhat.com> | 2015-04-01 13:24:54 +0200 |
commit | 94729eef71570e0b792a9afb95eeab7fd1eec56b (patch) | |
tree | 1c09d92fc29764f1bf7322d13487caabb19002be /async/src | |
parent | fb4c36e3daded17746a0bcd7c245b8cea9782c1a (diff) | |
download | sink-94729eef71570e0b792a9afb95eeab7fd1eec56b.tar.gz sink-94729eef71570e0b792a9afb95eeab7fd1eec56b.zip |
Async: have the top executor reference itself during execution
The only reference to the top executor (the last in chain) is held by the
Job. If the Job goes out of scope after it's executed, the top Executor
is deleted (which in turn deletes the entire Executor chain). By having
the top Executor holding reference to itself during execution we ensure
that the Executor chain is not deleted until the job is finished, even
when the parent Job object is deleted in the meanwhile.
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()); |