Remove extra FLAGS_seed definition
[folly.git] / folly / Random.cpp
index 87da68b6b5216469591efd17ad68466fd1c00068..d1584f11edaa1de1f94351ab58816c299f100ebf 100644 (file)
 #include <atomic>
 #include <unistd.h>
 #include <sys/time.h>
+#include <mutex>
 #include <random>
 #include <array>
 
 #include <glog/logging.h>
 #include <folly/File.h>
 #include <folly/FileUtil.h>
+#include <folly/ThreadLocal.h>
+
+#ifdef _MSC_VER
+# include <wincrypt.h>
+#endif
 
 namespace folly {
 
 namespace {
 
 void readRandomDevice(void* data, size_t size) {
+#ifdef _MSC_VER
+  static std::once_flag flag;
+  static HCRYPTPROV cryptoProv;
+  std::call_once(flag, [&] {
+    PCHECK(CryptAcquireContext(&cryptoProv, nullptr, nullptr,
+                               PROV_RSA_FULL, 0));
+  });
+  CHECK(size <= std::numeric_limits<DWORD>::max());
+  PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data));
+#else
   // Keep the random device open for the duration of the program.
   static int randomFd = ::open("/dev/urandom", O_RDONLY);
   PCHECK(randomFd >= 0);
   auto bytesRead = readFull(randomFd, data, size);
   PCHECK(bytesRead >= 0 && size_t(bytesRead) == size);
+#endif
 }
 
 class BufferedRandomDevice {
@@ -100,11 +117,6 @@ void Random::secureRandom(void* data, size_t size) {
   bufferedRandomDevice->get(data, size);
 }
 
-ThreadLocalPRNG::ThreadLocalPRNG() {
-  static folly::ThreadLocal<ThreadLocalPRNG::LocalInstancePRNG> localInstance;
-  local_ = localInstance.get();
-}
-
 class ThreadLocalPRNG::LocalInstancePRNG {
  public:
   LocalInstancePRNG() : rng(Random::create()) { }
@@ -112,6 +124,11 @@ class ThreadLocalPRNG::LocalInstancePRNG {
   Random::DefaultGenerator rng;
 };
 
+ThreadLocalPRNG::ThreadLocalPRNG() {
+  static folly::ThreadLocal<ThreadLocalPRNG::LocalInstancePRNG> localInstance;
+  local_ = localInstance.get();
+}
+
 uint32_t ThreadLocalPRNG::getImpl(LocalInstancePRNG* local) {
   return local->rng();
 }