TEST(AsyncTask, RequestCoalescingMultithreaded) { RunLoop loop; unsigned count = 0; AsyncTask async([&count] { ++count; }); std::vector<std::unique_ptr<Thread<TestWorker>>> threads; ThreadContext context = {"Test"}; unsigned numThreads = 25; for (unsigned i = 0; i < numThreads; ++i) { std::unique_ptr<Thread<TestWorker>> thread = std::make_unique<Thread<TestWorker>>(context, &async); thread->invoke(&TestWorker::run); threads.push_back(std::move(thread)); } // Join all the threads threads.clear(); loop.runOnce(); EXPECT_EQ(count, 1u); }
TEST(AsyncTask, DestroyAfterSignaling) { RunLoop loop; // We're creating two tasks and signal both of them; the one that gets fired first destroys // the other one. Make sure that the second one we destroyed doesn't fire. std::unique_ptr<AsyncTask> task1, task2; task1 = std::make_unique<AsyncTask>([&] { task2.reset(); if (!task1) { FAIL() << "Task was destroyed but invoked anyway"; } }); task2 = std::make_unique<AsyncTask>([&] { task1.reset(); if (!task2) { FAIL() << "Task was destroyed but invoked anyway"; } }); task1->send(); task2->send(); loop.runOnce(); }
TEST(AsyncTask, RequestCoalescingMultithreaded) { RunLoop loop; unsigned count = 0, numThreads = 25; AsyncTask async([&count] { ++count; }); auto retainer = Scheduler::GetBackground(); auto mailbox = std::make_shared<Mailbox>(*retainer); TestWorker worker(&async); ActorRef<TestWorker> workerRef(worker, mailbox); for (unsigned i = 0; i < numThreads; ++i) { workerRef.invoke(&TestWorker::run); } std::promise<void> barrier; std::future<void> barrierFuture = barrier.get_future(); workerRef.invoke(&TestWorker::sync, std::move(barrier)); barrierFuture.wait(); loop.runOnce(); EXPECT_EQ(count, 1u); }
TEST(AsyncTask, RequestCoalescing) { RunLoop loop; unsigned count = 0; AsyncTask async([&count] { ++count; }); async.send(); async.send(); async.send(); async.send(); async.send(); loop.runOnce(); EXPECT_EQ(count, 1u); }