summaryrefslogtreecommitdiff
path: root/test/util/async_task.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/util/async_task.cpp')
-rw-r--r--test/util/async_task.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/test/util/async_task.cpp b/test/util/async_task.cpp
new file mode 100644
index 0000000000..8073670fe1
--- /dev/null
+++ b/test/util/async_task.cpp
@@ -0,0 +1,126 @@
+#include <mbgl/util/async_task.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/thread.hpp>
+
+#include "../fixtures/util.hpp"
+
+#include <vector>
+
+using namespace mbgl::util;
+
+namespace {
+
+class TestWorker {
+public:
+ TestWorker(AsyncTask *async_)
+ : async(async_) {}
+
+ void run() {
+ for (unsigned i = 0; i < 100000; ++i) {
+ async->send();
+ }
+ }
+
+ void runWithCallback(std::function<void()> cb) {
+ for (unsigned i = 0; i < 100000; ++i) {
+ async->send();
+ }
+
+ cb();
+ }
+
+private:
+ AsyncTask *async;
+};
+
+} // namespace
+
+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, 1);
+}
+
+TEST(AsyncTask, DestroyShouldNotRunQueue) {
+ RunLoop loop;
+
+ unsigned count = 0;
+ auto async = std::make_unique<AsyncTask>([&count] { ++count; });
+
+ async->send();
+ async.reset();
+
+ EXPECT_EQ(count, 0);
+}
+
+TEST(AsyncTask, RequestCoalescingMultithreaded) {
+ RunLoop loop;
+
+ unsigned count = 0;
+ AsyncTask async([&count] { ++count; });
+
+ std::vector<std::unique_ptr<Thread<TestWorker>>> threads;
+ ThreadContext context = {"Test", ThreadType::Map, ThreadPriority::Regular};
+
+ 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, 1);
+}
+
+TEST(AsyncTask, ThreadSafety) {
+ RunLoop loop;
+
+ unsigned count = 0;
+ AsyncTask async([&count] { ++count; });
+
+ unsigned numThreads = 25;
+
+ auto callback = [&] {
+ if (!--numThreads) {
+ loop.stop();
+ }
+ };
+
+ std::vector<std::unique_ptr<Thread<TestWorker>>> threads;
+ std::vector<std::unique_ptr<mbgl::WorkRequest>> requests;
+ ThreadContext context = {"Test", ThreadType::Map, ThreadPriority::Regular};
+
+ for (unsigned i = 0; i < numThreads; ++i) {
+ std::unique_ptr<Thread<TestWorker>> thread =
+ std::make_unique<Thread<TestWorker>>(context, &async);
+
+ requests.push_back(
+ thread->invokeWithCallback(&TestWorker::runWithCallback, callback));
+
+ threads.push_back(std::move(thread));
+ }
+
+ loop.run();
+
+ // We expect here more than 1 but 1 would also be
+ // a valid result, although very unlikely (I hope).
+ EXPECT_GT(count, 1);
+}