From: Andrii Grynenko <andrii@fb.com>
Date: Thu, 1 Dec 2016 00:50:04 +0000 (-0800)
Subject: Use SingletonThreadLocal in folly::Random
X-Git-Tag: v2016.12.05.00~8
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=895c8a62d25a854afc1cbf9d1f6fba97ba1b9d83;p=folly.git

Use SingletonThreadLocal in folly::Random

Summary: folly::SingletonThreadLocal should be used for all thread-local singletons to avoid SDOF.

Reviewed By: yfeldblum

Differential Revision: D4253009

fbshipit-source-id: 5b4ca57a7a77b7b54c94630a2a29d13b84a3af27
---

diff --git a/folly/Random.cpp b/folly/Random.cpp
index d4fb39b4..d991990e 100644
--- a/folly/Random.cpp
+++ b/folly/Random.cpp
@@ -21,13 +21,14 @@
 #include <random>
 #include <array>
 
-#include <glog/logging.h>
 #include <folly/CallOnce.h>
 #include <folly/File.h>
 #include <folly/FileUtil.h>
+#include <folly/SingletonThreadLocal.h>
 #include <folly/ThreadLocal.h>
 #include <folly/portability/SysTime.h>
 #include <folly/portability/Unistd.h>
+#include <glog/logging.h>
 
 #ifdef _MSC_VER
 # include <wincrypt.h>
@@ -123,28 +124,30 @@ void BufferedRandomDevice::getSlow(unsigned char* data, size_t size) {
   ptr_ += size;
 }
 
+struct RandomTag {};
 
-}  // namespace
+} // namespace
 
 void Random::secureRandom(void* data, size_t size) {
-  static ThreadLocal<BufferedRandomDevice> bufferedRandomDevice;
-  bufferedRandomDevice->get(data, size);
+  static SingletonThreadLocal<BufferedRandomDevice, RandomTag>
+      bufferedRandomDevice;
+  bufferedRandomDevice.get().get(data, size);
 }
 
 class ThreadLocalPRNG::LocalInstancePRNG {
  public:
-  LocalInstancePRNG() : rng(Random::create()) { }
+  LocalInstancePRNG() : rng(Random::create()) {}
 
   Random::DefaultGenerator rng;
 };
 
 ThreadLocalPRNG::ThreadLocalPRNG() {
-  static folly::ThreadLocal<ThreadLocalPRNG::LocalInstancePRNG> localInstance;
-  local_ = localInstance.get();
+  static SingletonThreadLocal<ThreadLocalPRNG::LocalInstancePRNG, RandomTag>
+      localInstancePRNG;
+  local_ = &localInstancePRNG.get();
 }
 
 uint32_t ThreadLocalPRNG::getImpl(LocalInstancePRNG* local) {
   return local->rng();
 }
-
 }
diff --git a/folly/Random.h b/folly/Random.h
index 0962d07e..0e52772a 100644
--- a/folly/Random.h
+++ b/folly/Random.h
@@ -65,9 +65,9 @@ class ThreadLocalPRNG {
 
   ThreadLocalPRNG();
 
- private:
   class LocalInstancePRNG;
 
+ private:
   static result_type getImpl(LocalInstancePRNG* local);
   LocalInstancePRNG* local_;
 };