From 953890fe4471c0b34e0f6b24b8c7ebaed7d7ed87 Mon Sep 17 00:00:00 2001 From: Phil Willoughby Date: Wed, 14 Sep 2016 01:53:09 -0700 Subject: [PATCH] Test for folly::SingletonThreadLocal Summary: Validates that we create a distinct singleton for each thread and that each such singleton is destroyed at its owning-thread's exit. Reviewed By: yfeldblum Differential Revision: D3849146 fbshipit-source-id: af878b32ecfc6c82b866d7a805e1385d74a8a5f5 --- folly/test/Makefile.am | 4 ++ folly/test/SingletonThreadLocalTest.cpp | 68 +++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 folly/test/SingletonThreadLocalTest.cpp diff --git a/folly/test/Makefile.am b/folly/test/Makefile.am index 0ee3e1ff..a227287a 100644 --- a/folly/test/Makefile.am +++ b/folly/test/Makefile.am @@ -309,4 +309,8 @@ partial_test_SOURCES = PartialTest.cpp partial_test_LDADD = libfollytestmain.la TESTS += partial_test +singleton_thread_local_test_SOURCES = SingletonThreadLocalTest.cpp +singleton_thread_local_test_LDADD = libfollytestmain.la +TESTS += singleton_thread_local_test + check_PROGRAMS += $(TESTS) diff --git a/folly/test/SingletonThreadLocalTest.cpp b/folly/test/SingletonThreadLocalTest.cpp new file mode 100644 index 00000000..5b329182 --- /dev/null +++ b/folly/test/SingletonThreadLocalTest.cpp @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include + +#include + +using namespace folly; + +namespace { +static std::atomic fooCreatedCount{0}; +static std::atomic fooDeletedCount{0}; +struct Foo { + Foo() { + ++fooCreatedCount; + } + ~Foo() { + ++fooDeletedCount; + } +}; +using FooSingletonTL = SingletonThreadLocal; +FooSingletonTL theFooSingleton; +} + +TEST(SingletonThreadLocalTest, OneSingletonPerThread) { + const std::size_t targetThreadCount{64}; + std::atomic completedThreadCount{0}; + Synchronized> fooAddresses{}; + std::vector threads{}; + auto threadFunction = + [&fooAddresses, targetThreadCount, &completedThreadCount] { + fooAddresses.wlock()->emplace(&FooSingletonTL::get()); + ++completedThreadCount; + while (completedThreadCount < targetThreadCount) { + std::this_thread::yield(); + } + }; + { + for (std::size_t threadCount{0}; threadCount < targetThreadCount; + ++threadCount) { + threads.emplace_back(threadFunction); + } + } + for (auto& thread : threads) { + thread.join(); + } + EXPECT_EQ(threads.size(), fooAddresses.rlock()->size()); + EXPECT_EQ(threads.size(), fooCreatedCount); + EXPECT_EQ(threads.size(), fooDeletedCount); +} -- 2.34.1