Fix fibers gdb utils script
[folly.git] / folly / Random.cpp
index 9b960de0530e21ade261511173dc8a01b6c2562c..d4fb39b4ea3a4eaaa1d9140dfe422bcdd610a090 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Facebook, Inc.
+ * 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.
 #include <folly/Random.h>
 
 #include <atomic>
-#include <unistd.h>
-#include <sys/time.h>
 #include <mutex>
 #include <random>
 #include <array>
 
 #include <glog/logging.h>
+#include <folly/CallOnce.h>
 #include <folly/File.h>
 #include <folly/FileUtil.h>
+#include <folly/ThreadLocal.h>
+#include <folly/portability/SysTime.h>
+#include <folly/portability/Unistd.h>
 
 #ifdef _MSC_VER
 # include <wincrypt.h>
@@ -37,11 +39,24 @@ namespace {
 
 void readRandomDevice(void* data, size_t size) {
 #ifdef _MSC_VER
-  static std::once_flag flag;
+  static folly::once_flag flag;
   static HCRYPTPROV cryptoProv;
-  std::call_once(flag, [&] {
-    PCHECK(CryptAcquireContext(&cryptoProv, nullptr, nullptr,
-                               PROV_RSA_FULL, 0));
+  folly::call_once(flag, [&] {
+    if (!CryptAcquireContext(
+            &cryptoProv,
+            nullptr,
+            nullptr,
+            PROV_RSA_FULL,
+            CRYPT_VERIFYCONTEXT)) {
+      if (GetLastError() == NTE_BAD_KEYSET) {
+        // Mostly likely cause of this is that no key container
+        // exists yet, so try to create one.
+        PCHECK(CryptAcquireContext(
+            &cryptoProv, nullptr, nullptr, PROV_RSA_FULL, CRYPT_NEWKEYSET));
+      } else {
+        LOG(FATAL) << "Failed to acquire the default crypto context.";
+      }
+    }
   });
   CHECK(size <= std::numeric_limits<DWORD>::max());
   PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data));
@@ -108,14 +123,14 @@ void BufferedRandomDevice::getSlow(unsigned char* data, size_t size) {
   ptr_ += size;
 }
 
+
 }  // namespace
 
 void Random::secureRandom(void* data, size_t size) {
-  static thread_local BufferedRandomDevice bufferedRandomDevice;
-  bufferedRandomDevice.get(data, size);
+  static ThreadLocal<BufferedRandomDevice> bufferedRandomDevice;
+  bufferedRandomDevice->get(data, size);
 }
 
-
 class ThreadLocalPRNG::LocalInstancePRNG {
  public:
   LocalInstancePRNG() : rng(Random::create()) { }
@@ -124,8 +139,8 @@ class ThreadLocalPRNG::LocalInstancePRNG {
 };
 
 ThreadLocalPRNG::ThreadLocalPRNG() {
-  static thread_local ThreadLocalPRNG::LocalInstancePRNG localInstance;
-  local_ = &localInstance;
+  static folly::ThreadLocal<ThreadLocalPRNG::LocalInstancePRNG> localInstance;
+  local_ = localInstance.get();
 }
 
 uint32_t ThreadLocalPRNG::getImpl(LocalInstancePRNG* local) {