31 #include <glog/logging.h> 41 void readRandomDevice(
void*
data,
size_t size) {
44 static HCRYPTPROV cryptoProv;
46 if (!CryptAcquireContext(
51 CRYPT_VERIFYCONTEXT)) {
52 if (GetLastError() == NTE_BAD_KEYSET) {
55 PCHECK(CryptAcquireContext(
56 &cryptoProv,
nullptr,
nullptr, PROV_RSA_FULL, CRYPT_NEWKEYSET));
58 LOG(FATAL) <<
"Failed to acquire the default crypto context.";
63 PCHECK(CryptGenRandom(cryptoProv, (DWORD)size, (BYTE*)data));
66 static int randomFd = ::open(
"/dev/urandom", O_RDONLY | O_CLOEXEC);
67 PCHECK(randomFd >= 0);
68 auto bytesRead =
readFull(randomFd, data, size);
69 PCHECK(bytesRead >= 0 &&
size_t(bytesRead) == size);
73 class BufferedRandomDevice {
78 static void notifyNewGlobalEpoch() {
82 explicit BufferedRandomDevice(
size_t bufferSize = kDefaultBufferSize);
85 auto const globalEpoch =
globalEpoch_.load(std::memory_order_relaxed);
86 if (
LIKELY(globalEpoch ==
epoch_ && size <= remaining())) {
87 memcpy(data,
ptr_, size);
90 getSlow(static_cast<unsigned char*>(data), size);
95 void getSlow(
unsigned char* data,
size_t size);
97 inline size_t remaining()
const {
113 BufferedRandomDevice::BufferedRandomDevice(
size_t bufferSize)
115 buffer_(
new unsigned char[bufferSize]),
120 []() {
return true; },
125 BufferedRandomDevice::notifyNewGlobalEpoch();
131 auto const globalEpoch =
globalEpoch_.load(std::memory_order_relaxed);
132 if (globalEpoch !=
epoch_) {
137 DCHECK_GT(size, remaining());
140 readRandomDevice(data, size);
144 size_t copied = remaining();
145 memcpy(data,
ptr_, copied);
153 memcpy(data, ptr_, size);
static std::enable_if< std::is_integral< T >::value &&!std::is_same< T, bool >::value, T >::type secureRandom()
ssize_t readFull(int fd, void *buf, size_t count)
—— Concurrent Priority Queue Implementation ——
static constexpr size_t kDefaultBufferSize
FOLLY_ALWAYS_INLINE void call_once(basic_once_flag< Mutex, Atom > &flag, F &&f, Args &&...args)
constexpr auto size(C const &c) -> decltype(c.size())
static std::atomic< size_t > globalEpoch_
constexpr auto data(C &c) -> decltype(c.data())
basic_once_flag< SharedMutex > once_flag
std::mt19937 DefaultGenerator
PUSHMI_INLINE_VAR constexpr detail::get_fn< T > get
std::unique_ptr< unsigned char[]> buffer_
static void registerHandler(void *object, folly::Function< bool()> prepare, folly::Function< void()> parent, folly::Function< void()> child)