diff options
author | Dan Vrátil <dvratil@redhat.com> | 2015-04-01 21:02:34 +0200 |
---|---|---|
committer | Dan Vrátil <dvratil@redhat.com> | 2015-04-01 21:19:48 +0200 |
commit | b01fadba903056218f2a00c5e62e1dc8df062124 (patch) | |
tree | adca72675973ab5d8253ab14ff94949824d6523e /async/autotests/asynctest.cpp | |
parent | 94729eef71570e0b792a9afb95eeab7fd1eec56b (diff) | |
download | sink-b01fadba903056218f2a00c5e62e1dc8df062124.tar.gz sink-b01fadba903056218f2a00c5e62e1dc8df062124.zip |
Async: support (re-)executing single Job multiple times
Storing Future and current Job progress directly in Executors means
that we cannot re-execute finished job, or even execute the same Job
multiple times in parallel. To do so, we need to make Executors stateless
and track the state elsewhere.
This change does that by moving the execution state from Executor to Execution
class. Executors now only describe the tasks to execute, while Execution holds
the current state of execution. New Execution is created every time Job::exec()
is called.
Execution holds reference to it's result (Future) and Executor which created
the Execution. This ensures that Executor is not deleted when Job (which owns
Executors) goes out of scope while the execution is still running. At the same
time Future holds reference to relevant Execution, so that the Execution is
deleted when all copies of Future referring result from the respective Execution
are deleted.
Diffstat (limited to 'async/autotests/asynctest.cpp')
-rw-r--r-- | async/autotests/asynctest.cpp | 48 |
1 files changed, 12 insertions, 36 deletions
diff --git a/async/autotests/asynctest.cpp b/async/autotests/asynctest.cpp index 78a834e..c507721 100644 --- a/async/autotests/asynctest.cpp +++ b/async/autotests/asynctest.cpp | |||
@@ -68,9 +68,6 @@ private Q_SLOTS: | |||
68 | void testLifetimeWithoutHandle(); | 68 | void testLifetimeWithoutHandle(); |
69 | void testLifetimeWithHandle(); | 69 | void testLifetimeWithHandle(); |
70 | 70 | ||
71 | void testWhile(); | ||
72 | void testWhileWithoutCondition(); | ||
73 | |||
74 | void benchmarkSyncThenExecutor(); | 71 | void benchmarkSyncThenExecutor(); |
75 | 72 | ||
76 | private: | 73 | private: |
@@ -343,6 +340,8 @@ void AsyncTest::testSyncEach() | |||
343 | 340 | ||
344 | void AsyncTest::testJoinedEach() | 341 | void AsyncTest::testJoinedEach() |
345 | { | 342 | { |
343 | QFAIL("Crashes due to bad lifetime of Future"); | ||
344 | |||
346 | auto job1 = Async::start<QList<int>, int>( | 345 | auto job1 = Async::start<QList<int>, int>( |
347 | [](int v, Async::Future<QList<int>> &future) { | 346 | [](int v, Async::Future<QList<int>> &future) { |
348 | new AsyncSimulator<QList<int>>(future, { v * 2 }); | 347 | new AsyncSimulator<QList<int>>(future, { v * 2 }); |
@@ -380,39 +379,6 @@ void AsyncTest::testVoidEach() | |||
380 | QCOMPARE(check, expected); | 379 | QCOMPARE(check, expected); |
381 | } | 380 | } |
382 | 381 | ||
383 | void AsyncTest::testWhile() | ||
384 | { | ||
385 | |||
386 | QList<int> processed; | ||
387 | QList<int> list({1, 2, 3, 4}); | ||
388 | auto it = QSharedPointer<QListIterator<int> >::create(list); | ||
389 | Async::dowhile( | ||
390 | [it]() -> bool { return it->hasNext(); }, | ||
391 | [it, &processed](Async::Future<void> future) { | ||
392 | auto value = it->next(); | ||
393 | processed << value; | ||
394 | future.setFinished(); | ||
395 | } | ||
396 | ).exec().waitForFinished(); | ||
397 | QCOMPARE(processed, list); | ||
398 | } | ||
399 | |||
400 | void AsyncTest::testWhileWithoutCondition() | ||
401 | { | ||
402 | |||
403 | QList<int> processed; | ||
404 | QList<int> list({1, 2, 3, 4}); | ||
405 | auto it = QSharedPointer<QListIterator<int> >::create(list); | ||
406 | Async::dowhile( | ||
407 | [it, &processed](Async::Future<bool> future) { | ||
408 | auto value = it->next(); | ||
409 | processed << value; | ||
410 | future.setValue(it->hasNext()); | ||
411 | future.setFinished(); | ||
412 | } | ||
413 | ).exec().waitForFinished(); | ||
414 | QCOMPARE(processed, list); | ||
415 | } | ||
416 | 382 | ||
417 | 383 | ||
418 | 384 | ||
@@ -563,7 +529,12 @@ void AsyncTest::testChainingRunningJob() | |||
563 | QVERIFY(!future1.isFinished()); | 529 | QVERIFY(!future1.isFinished()); |
564 | future2.waitForFinished(); | 530 | future2.waitForFinished(); |
565 | 531 | ||
532 | QEXPECT_FAIL("", "Chaining new job to a running job no longer executes the new job. " | ||
533 | "This is a trade-off for being able to re-execute single job multiple times.", | ||
534 | Abort); | ||
535 | |||
566 | QCOMPARE(check, 2); | 536 | QCOMPARE(check, 2); |
537 | |||
567 | QVERIFY(future1.isFinished()); | 538 | QVERIFY(future1.isFinished()); |
568 | QVERIFY(future2.isFinished()); | 539 | QVERIFY(future2.isFinished()); |
569 | QCOMPARE(future1.value(), 42); | 540 | QCOMPARE(future1.value(), 42); |
@@ -592,7 +563,12 @@ void AsyncTest::testChainingFinishedJob() | |||
592 | auto future2 = job2.exec(); | 563 | auto future2 = job2.exec(); |
593 | QVERIFY(future2.isFinished()); | 564 | QVERIFY(future2.isFinished()); |
594 | 565 | ||
566 | QEXPECT_FAIL("", "Resuming finished job by chaining a new job and calling exec() is no longer suppported. " | ||
567 | "This is a trade-off for being able to re-execute single job multiple times.", | ||
568 | Abort); | ||
569 | |||
595 | QCOMPARE(check, 2); | 570 | QCOMPARE(check, 2); |
571 | |||
596 | QCOMPARE(future1.value(), 42); | 572 | QCOMPARE(future1.value(), 42); |
597 | QCOMPARE(future2.value(), 84); | 573 | QCOMPARE(future2.value(), 84); |
598 | } | 574 | } |