summaryrefslogtreecommitdiffstats
path: root/async/autotests/asynctest.cpp
diff options
context:
space:
mode:
authorDan Vrátil <dvratil@redhat.com>2015-04-01 21:02:34 +0200
committerDan Vrátil <dvratil@redhat.com>2015-04-01 21:19:48 +0200
commitb01fadba903056218f2a00c5e62e1dc8df062124 (patch)
treeadca72675973ab5d8253ab14ff94949824d6523e /async/autotests/asynctest.cpp
parent94729eef71570e0b792a9afb95eeab7fd1eec56b (diff)
downloadsink-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.cpp48
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
76private: 73private:
@@ -343,6 +340,8 @@ void AsyncTest::testSyncEach()
343 340
344void AsyncTest::testJoinedEach() 341void 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
383void 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
400void 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}