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::AsyncRequest>> requests;
    ThreadContext context = {"Test"};

    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, 0u);
}
TEST(AsyncTask, ThreadSafety) {
    RunLoop loop;

    unsigned count = 0, numThreads = 25;
    std::atomic_uint completed(numThreads);

    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) {
        // The callback runs on the worker, thus the atomic type.
        workerRef.invoke(&TestWorker::runWithCallback, [&] { if (!--completed) loop.stop(); });
    }

    loop.run();

    // We expect here more than 1 but 1 would also be
    // a valid result, although very unlikely (I hope).
    EXPECT_GT(count, 0u);
}
Example #3
0
TEST(Timer, Repeat) {
    RunLoop loop;

    Timer timer;

    unsigned count = 10;
    auto callback = [&] {
        if (!--count) {
            loop.stop();
        }
    };

    auto interval = std::chrono::milliseconds(50);
    auto expectedTotalTime = interval * count;

    auto first = mbgl::Clock::now();
    timer.start(interval, interval, callback);

    loop.run();

    using namespace std::chrono;
    auto totalTime = duration_cast<milliseconds>(mbgl::Clock::now() - first);

    EXPECT_GE(totalTime, expectedTotalTime * 0.8);
    EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
Example #4
0
TEST(Timer, StartOverrides) {
    RunLoop loop;

    Timer timer;

    auto interval1 = std::chrono::milliseconds(50);
    auto interval2 = std::chrono::milliseconds(250);
    auto expectedTotalTime = interval1  + interval2;

    int count = 0;

    auto callback2 = [&] {
        ++count;
        loop.stop();
    };

    auto callback1 = [&] {
        ++count;
        timer.start(interval2, mbgl::Duration::zero(), callback2);
    };

    auto first = mbgl::Clock::now();
    timer.start(interval1, mbgl::Duration::zero(), callback1);

    loop.run();

    using namespace std::chrono;
    auto totalTime = duration_cast<milliseconds>(mbgl::Clock::now() - first);

    EXPECT_EQ(count, 2);

    EXPECT_GE(totalTime, expectedTotalTime * 0.8);
    EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
Example #5
0
TEST(Timer, DestroyShouldStop) {
    RunLoop loop;

    auto timer1 = std::make_unique<Timer>();
    Timer timer2;

    auto interval1 = std::chrono::milliseconds(50);
    auto interval2 = std::chrono::milliseconds(250);
    auto expectedTotalTime = interval2;

    int count = 0;

    auto callback1 = [&] {
        ++count;
        timer1.reset();
    };

    auto callback2 = [&] {
        ++count;
        loop.stop();
    };

    auto first = mbgl::Clock::now();
    timer1->start(interval1, interval1, callback1);
    timer2.start(interval2, mbgl::Duration::zero(), callback2);

    loop.run();

    using namespace std::chrono;
    auto totalTime = duration_cast<milliseconds>(mbgl::Clock::now() - first);

    EXPECT_EQ(count, 2);

    EXPECT_GE(totalTime, expectedTotalTime * 0.8);
    EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}
Example #6
0
TEST(Timer, Basic) {
    RunLoop loop;

    Timer timer;

    auto callback = [&loop] { loop.stop(); };

    auto interval = std::chrono::milliseconds(300);
    auto expectedTotalTime = interval;

    auto first = mbgl::Clock::now();
    timer.start(interval, mbgl::Duration::zero(), callback);

    loop.run();

    using namespace std::chrono;
    auto totalTime = duration_cast<milliseconds>(mbgl::Clock::now() - first);

    // These are not high precision timers. Especially libuv uses
    // cached time from the beginning of of the main loop iteration
    // and it is very prone to fire earlier, which is, odd.
    EXPECT_GE(totalTime, expectedTotalTime * 0.8);
    EXPECT_LE(totalTime, expectedTotalTime * 1.2);
}