#include #include #include #include using namespace mbgl::util; namespace { class TestThread { public: TestThread(int *number_) { number.set(number_); } ~TestThread() { number.set(nullptr); } int getNumber() { return *number.get(); } private: static ThreadLocal number; }; ThreadLocal TestThread::number; } // namespace TEST(ThreadLocalStorage, Basic) { RunLoop loop; int number1 = 1; int number2 = 2; int number3 = 3; ThreadContext context = {"Test"}; Thread thread1(context, &number1); Thread thread2(context, &number2); Thread thread3(context, &number3); EXPECT_EQ(number1, thread1.invokeSync(&TestThread::getNumber)); EXPECT_EQ(number2, thread2.invokeSync(&TestThread::getNumber)); EXPECT_EQ(number3, thread3.invokeSync(&TestThread::getNumber)); } TEST(ThreadLocalStorage, NotSetReturnsNull) { static ThreadLocal number; EXPECT_EQ(nullptr, number.get()); } namespace { struct DtorCounter { ~DtorCounter() { ++(*value); } unsigned *value; }; class TestThreadReclaim { public: TestThreadReclaim(DtorCounter* counter_) { counter.set(counter_); } private: static ThreadLocal counter; }; ThreadLocal TestThreadReclaim::counter; } // namespace TEST(ThreadLocalStorage, AutoReclaim) { RunLoop loop; unsigned counter = 0; DtorCounter* dtorCounter1 = new DtorCounter{ &counter }; DtorCounter* dtorCounter2 = new DtorCounter{ &counter }; ThreadContext context = {"Test"}; auto thread1 = std::make_unique>(context, dtorCounter1); auto thread2 = std::make_unique>(context, dtorCounter2); thread1.reset(); thread2.reset(); EXPECT_EQ(counter, 2); }